Mongoose.js findOne 返回查询元数据

Posted

技术标签:

【中文标题】Mongoose.js findOne 返回查询元数据【英文标题】:Mongoose.js findOne returning query metadata 【发布时间】:2017-04-15 07:10:55 【问题描述】:

我正在尝试在我的数据库上运行 mongoose.findOne,但我得到了意想不到的结果。我的查询是

const User = mongoose.model('User', name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array )


exports.findUser = function findUser(email)

    const foundUser = User.findOne(email: email, function(err, userObj)
        if(err)
            return err
               else if (userObj)
            return userObj
               else
            return null
        
    )

    return foundUser

但是这会返回以下数据(似乎是随机的?)并且没有我请求的数据

Query 
  _mongooseOptions: ,
  mongooseCollection: 
   NativeCollection 
     collection: null,
     opts:  bufferCommands: true, capped: false ,
     name: 'users',
     collectionName: 'users',
     conn: 
      NativeConnection 
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: 'ds113938.mlab.com',
        port: 13938,
        user: 'root',
        pass: 'root',
        name: 'users',
        options: [Object],
        otherDbs: [],
        _readyState: 2,
        _closeCalled: false,
        _hasOpened: false,
        _listening: false,
        db: [Object] ,
     queue: [],
     buffer: true,
     emitter: 
      EventEmitter 
        domain: null,
        _events: ,
        _eventsCount: 0,
        _maxListeners: undefined  ,
  model: 
    [Function: model]
     hooks: Kareem  _pres: , _posts:  ,
     base: 
      Mongoose 
        connections: [Object],
        plugins: [],
        models: [Object],
        modelSchemas: [Object],
        options: [Object] ,
     modelName: 'User',
     model: [Function: model],
     db: 
      NativeConnection 
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: 'ds113938.mlab.com',
        port: 13938,
        user: 'root',
        pass: 'root',
        name: 'users',
        options: [Object],
        otherDbs: [],
        _readyState: 2,
        _closeCalled: false,
        _hasOpened: false,
        _listening: false,
        db: [Object] ,
     discriminators: undefined,
     schema: 
      Schema 
        obj: [Object],
        paths: [Object],
        subpaths: ,
        virtuals: [Object],
        singleNestedPaths: ,
        nested: ,
        inherits: ,
        callQueue: [Object],
        _indexes: [],
        methods: ,
        statics: ,
        tree: [Object],
        _requiredpaths: undefined,
        discriminatorMapping: undefined,
        _indexedpaths: undefined,
        query: ,
        childSchemas: [],
        s: [Object],
        options: [Object],
        '$globalPluginsApplied': true ,
     collection: 
      NativeCollection 
        collection: null,
        opts: [Object],
        name: 'users',
        collectionName: 'users',
        conn: [Object],
        queue: [],
        buffer: true,
        emitter: [Object] ,
     Query:  [Function] base: [Object] ,
     '$__insertMany': [Function],
     insertMany: [Function] ,
  schema: 
   Schema 
     obj: 
       name: [Function: String],
        email: [Function: String],
        passwordHash: [Function: String],
        validation: [Function: String],
        validationCode: [Function: String],
        favorites: [Function: Array] ,
     paths: 
       name: [Object],
        email: [Object],
        passwordHash: [Object],
        validation: [Object],
        validationCode: [Object],
        favorites: [Object],
        _id: [Object],
        __v: [Object] ,
     subpaths: ,
     virtuals:  id: [Object] ,
     singleNestedPaths: ,
     nested: ,
     inherits: ,
     callQueue: [ [Object], [Object], [Object], [Object] ],
     _indexes: [],
     methods: ,
     statics: ,
     tree: 
       name: [Function: String],
        email: [Function: String],
        passwordHash: [Function: String],
        validation: [Function: String],
        validationCode: [Function: String],
        favorites: [Function: Array],
        _id: [Object],
        id: [Object],
        __v: [Function: Number] ,
     _requiredpaths: undefined,
     discriminatorMapping: undefined,
     _indexedpaths: undefined,
     query: ,
     childSchemas: [],
     s:  hooks: [Object], kareemHooks: [Object] ,
     options: 
       retainKeyOrder: false,
        typeKey: 'type',
        id: true,
        noVirtualId: false,
        _id: true,
        noId: false,
        validateBeforeSave: true,
        read: null,
        shardKey: null,
        autoIndex: null,
        minimize: true,
        discriminatorKey: '__t',
        versionKey: '__v',
        capped: false,
        bufferCommands: true,
        strict: true,
        pluralization: true ,
     '$globalPluginsApplied': true ,
  op: 'findOne',
  options:  retainKeyOrder: false ,
  _conditions:  email: 'Adam@gmail.com' ,
  _fields: undefined,
  _update: undefined,
  _path: undefined,
  _distinct: undefined,
  _collection: 
   NodeCollection 
     collection: 
      NativeCollection 
        collection: null,
        opts: [Object],
        name: 'users',
        collectionName: 'users',
        conn: [Object],
        queue: [],
        buffer: true,
        emitter: [Object] ,
     collectionName: 'users' ,
  _traceFunction: undefined,
  _castError: null,
  _count: [Function],
  _execUpdate: [Function],
  _find: [Function],
  _findOne: [Function],
  _findOneAndRemove: [Function],
  _findOneAndUpdate: [Function] 

我想知道如何解决这个问题,这似乎是我尝试运行的查询的概述,而不是所述查询的结果

【问题讨论】:

【参考方案1】:

只需修改你已有的内容...


  ...
  return foundUser.toJSON();

这将返回实际的文档/值(不含 Query 的元数据)。

【讨论】:

【参考方案2】:

问题是您甚至在查询完成之前就返回了foundUser object。这就是为什么您将查询对象作为响应而不是文档对象。

有错误的代码 ` const User = mongoose.model('User', name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array )

exports.findUser = function findUser(email)

const foundUser = User.findOne(email: email, function(err, userObj)
    if(err)
        return err
           else if (userObj)
        return userObj
           else
        return null
    
)

return foundUser

`

代码没有错误 const User = mongoose.model('User', name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array )

exports.findUser = function findUser(email)

const foundUser = User.findOne(email: email, function(err, userObj)
    if(err)
        return err
           else if (userObj)
        return userObj
           else
        return null
    
)

【讨论】:

【参考方案3】:

我最近遇到了同样的问题。

在我的例子中,在运行之前已经制定了一个解决方案,尽管在这种情况下该方法必须是异步的。

如下:

async findUser(email,callback)
    const foundUser = await User.findOne(email: email, (err, userObj)=>
        if(err)
            callback(err)
         else if (userObj)
            callback(null,userObj)
         else 
            callback(new Error('Some strange thing has happened));
        
    );

【讨论】:

【参考方案4】:

试试这个:

const User = mongoose.model('User', name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array )


exports.findUser = function findUser(email, callback)
    User.findOne(email: email, function(err, userObj)
        if(err)
            return callback(err);
         else if (userObj)
            return callback(null,userObj);
         else 
            return callback();
        
    );

当您执行 User.findOne 时,猫鼬会调用 mongodb 并在回调中返回您的用户(findOne 函数中的最后一个参数),以便返回找到的用户调用回调。

要调用findUser 函数,您需要传递一个回调,如下所示:

findUser('adam@gmail.com', function(error, userFound) 
   console.log(userFound);
);

您可以找到有关 Mongoose findOne here 的更多详细信息,要了解回调函数,您可以查看 here

【讨论】:

该死,快了 9 秒 :D @xShirase,最有趣的是我们的答案非常相似。哈哈 好吧,没有一百万种方法可以进行猫鼬查询 :) 虽然我的方法更详细,而且我使用 ES6 箭头函数,因为 OP 使用了 const。我赢了! 正如你所说,我试图暗示这一点。但是当我调用它时,我收到 TypeError 的错误:回调不是函数。我称它为 finduser('adam@gmail.com') 是正确的。或者我如何实现回调? 您需要致电findUser('adam@gmail.com', function(error, userFound)console.log(userFound);),这样您才能看到找到的用户。【参考方案5】:

您看到的是 return foundUser 的结果,这是一个 Mongoose 查询对象。

你正在混合同步和异步代码,你必须等待你的查询被执行并回调到调用它的函数,像这样:

const User = mongoose.model('User', name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array );

exports.findUser = function findUser(email,callback)
    const foundUser = User.findOne(email: email, (err, userObj)=>
        if(err)
            callback(err)
         else if (userObj)
            callback(null,userObj)
         else 
            callback(new Error('Some strange thing has happened));
        
    );

然后你像这样调用你的函数:

findUser((err,user)=>
    if(err) console.log(err);
    console.log(user)
);

对于回调的快速介绍,这是以What is a callback function?开头的链接

【讨论】:

以上是关于Mongoose.js findOne 返回查询元数据的主要内容,如果未能解决你的问题,请参考以下文章

mongoose.js 中带有查询生成器的 OR 运算符

Mongoose JS - 填充方法不返回完整引用的对象... - 仅返回 objectId 版本

如何在 mongoose.js 中获取最新和最旧的记录(或者只是它们之间的时间跨度)

TypeORM 在使用 .find()/.findOne() 时返回 undefined

猫鼬 findOne 方法返回 null

如何模拟像findOne()这样的mongoose查询?