【问题标题】:Mongoose How to get a nested object within a document via findOneMongoose 如何通过 findOne 在文档中获取嵌套对象
【发布时间】:2020-10-07 07:18:43
【问题描述】:

我需要在某个文档(按用户 ID 搜索)中获取一个嵌套对象,该文档内部也有一个对象(不能保证该对象将是同一个对象)。

我的用户模型是:

const mongoose = require('mongoose');
const { bool } = require('@hapi/joi');

const monitoringSchema = new mongoose.Schema({
    type: Object,
    default: {}
})

const hubSchema = new mongoose.Schema({
    hubID: {
        type: String,
        default: ""
    },
    isSetup: {
        type: Boolean,
        default: false
    },
    monitoring: {
        type: monitoringSchema
    }
}, {strict:false})

const finalUserSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true,
        max: 255
    },
    email: {
        type: String,
        required: true,
        max: 255,
    },
    password: {
        type: String,
        required: true,
        min: 10,
        max: 1024,
    },
    date: {
        type: Date,
        default: Date.now
    },
    isVerified: {
        type: Boolean,
        default: false
    },
    hub: {
        type: hubSchema
    }
},  {strict:false});

module.exports = mongoose.model('User', finalUserSchema);

或者它的布局:

_id: "id"
isVerified: true
username: "nathan"
email: "email@email.com"
hub:
    hubID: "id"
    monitoring: // WHOLE OBJECT I NEED TO RETREIVE
        exampleObject: 
            exampleValue: exampleKey

我有一组需要更新的用户 ID,我尝试了查询:

for(i in usersToUpdate){
        User.findOne({_id: usersToUpdate[i], "hub.monitoring": {}}, {}, callbackResponse);
        function callbackResponse(err, data){
            if(err) return console.log(err)
            console.log(data)
        }
    }

但它返回null 作为数据,所以显然查询是错误的。我知道错误是:

{_id: usersToUpdate[i], "hub.monitoring": {}}

更具体地说:

"hub.monitoring": {}

我正在使用{} 来引用监控中的对象,引用未知对象并取回其值的正确引用是什么,例如通配符?我试过了:

 {_id: usersToUpdate[i], "hub.monitoring": Object}

它仍然不起作用。我见过this answer,但是他们引用了一个他们已经知道的值,比如名字?

【问题讨论】:

  • 尝试使用"hub.monitoring": {$exists: true}
  • 如果知道hubID,你可以匹配"hub.hubID" : <hubID>,然后从javascript结果中提取monitoring对象。
  • @ShridharSharma 它可以工作,但仍然返回整个文档,我只想要返回文档中的 monitoring 对象.....
  • @ambianBeing 我不会知道hubID 除非我进行多个查询,我想避免这种情况,因为整个代码每天都会在我的数据库中的每个用户上运行...

标签: javascript node.js mongodb mongoose mongodb-query


【解决方案1】:

要仅检索monitoring 对象,可以使用aggregation 管道。

使用$match 过滤和$project 输出/抑制字段。

User.aggregate([
  {
    $match: {
      _id: mongoose.Types.ObjectId(usersToUpdate[i]),
    },
  },
  {
    $project: {
      monitoring: "$hub.monitoring",
      _id: 0,
    },
  },
]).exec(callbackResponse); 

Playground example

【讨论】:

  • 这确实有效,但是它将monitoring 对象中的所有其他对象返回为[Object],而不是它们的实际值?
  • @Nathan 您应该得到带有值的普通 javascript 对象,因为 mongoose 不会投射聚合管道。如果它们以字符串的形式出现(猫鼬不会因为聚合而将它们转换),还更新了将 id 显式转换为 ObjectId 的答案。试试看。此外,监控示例文档将有助于复制它,请显示。
【解决方案2】:

您可以尝试使用 findOne 的 2 对象形式,其中第一个对象是查询,第二个对象是您要返回的内容的投影。

User.findOne({_id: usersToUpdate[i]}, {"hub.monitoring": {$exists: true}}, callbackResponse);
function callbackResponse(err, data){
    if(err) return console.log(err)
    console.log(data)
}

这样,如果监控对象存在,就会返回该对象。

【讨论】:

  • 有人评论了这个答案,我回答说它仍然返回所涉及的整个文档,而不是单数 monitoring 对象......
  • 评论将hub.monitoring作为查询参数。将它放在第二个对象中会告诉您要返回文档的哪些字段。
猜你喜欢
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
  • 2017-04-01
  • 2020-05-02
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
相关资源
最近更新 更多