【问题标题】:MongoDB return nested array of objects minus a property within the object (also .then() doesn't work with aggregation)MongoDB 返回嵌套的对象数组减去对象内的属性(也 .then() 不适用于聚合)
【发布时间】:2020-10-04 02:01:17
【问题描述】:

我对 mongodb 很陌生,很难为我的用例找到解决方案。例如我有以下文件:

{ 
   _id : ObjectId('5rtgwr6gsrtbsr6hsfbsr6bdrfyb'),
   uuid : 'something',
   mainArray : [
       {
           id : 1,
           title: 'A',
           array: ['lots','off','stuff']
       },
       {
           id : 2,
           title: 'B',
           array: ['even','more','stuff']
       }
   ]
}

我希望返回以下内容:

{ 
   uuid : 'something',
   mainArray : [
       {
           id : 1,
           title: 'A'
       },
       {
           id : 2,
           title: 'B'
       }
   ]
}

我尝试了将findOne()aggregate()$slice$project 结合使用的各种组合。使用findOne(),如果它确实有效,将返回who 文档。我无法测试是否尝试聚合工作,因为 .then((ret)=>{}) 承诺似乎不适用于我的 node.js(findOne 没有问题)。像这样调用函数

return db.myCollection.aggregate([
    {
       $match: {
          _id:ObjectId(mongo_id)
       }  
    },
    {
        $project : {
            mainArray: {
                id:1,
                title:1
            }
        }
    }
],function(err,res){
    console.log(res)
    return res
})

记录整个函数,而不是我正在寻找的机器人。

【问题讨论】:

  • 对于只记录结果集,我认为你返回的是游标对象而不是结果集,试试return db.myCollection.aggregate([matchCode,projectCode]).toArray().then(data => { console.log(res); return res; }, error => {console.log(error)})
  • 另外,聚合函数中使用的 matchCode 和 projectCode 对象是什么?
  • 谢谢,问题已解决!我对如何构建项目代码的直觉是有效的,缺少的一块拼图是toArray()。我可以将 matchCode 和 projectCode 发给你,这样你至少可以把它作为我投票的答案。我很高兴我现在知道了,但是如何获得这样的知识呢?我在研究此问题时查看的任何网站和页面上都没有看到对它的引用。
  • 很高兴为您提供帮助,我将参考 mongodb 文档添加答案。不需要您的查询对象,因为这不是问题。

标签: node.js arrays mongodb nested slice


【解决方案1】:

您缺少获取实际结果集的 toArray() 方法。相反,您将返回聚合游标对象。试试这个。

return db.myCollection.aggregate([matchCode,projectCode]).toArray().then(
     data => { 
              console.log(data); 
              return data; 
             }, 
     error => { console.log(error)});

MongoDB NodeJS驱动的聚合游标文档可以 可以在这里找到 http://mongodb.github.io/node-mongodb-native/3.5/api/AggregationCursor.html#toArray

【讨论】:

    【解决方案2】:

    这是一个替代解决方案(@v1shva 在comment 中提到的解决方案)

    您可以使用.findOne() 操作的projection 选项来代替聚合。

    db.myCollection.findOne(matchCode, { 
      projection: { _id: false, 'mainArray.array': false } // or { _id: -1, 'mainArray.array': -1 }
    })
    

    【讨论】:

    • 有趣,谢谢!你能说使用这种方法比聚合有什么好处吗?编辑:也许我可以指定选择退出的一两个属性,而不是指定选择加入的属性?
    • 您实际上可以在聚合的$project 阶段的投影选项中使用相同的代码,以选择退出{ $project: { _id: false, 'mainArray.array': false } }。使用.findOne(),您将获得一份文件。使用.find().aggregate(),您可以获得多个文档。对于您的情况,没有其他区别。
    • 你能告诉我在mainArray 的第一个项目中返回array 的代码是什么,或者更确切地说是满足条件的项目,例如最近日期,以及其他所有项目忽略array?我觉得很厚颜无耻地问,没有付出任何努力自己去解决问题,但当我们都在寻找效率时,这似乎是另一件我可以不必要地花费无数时间的事情;)提前谢谢你!
    • @MikeyB 我们应该在哪里检查条件?骗取array 本身或mainArray 或文档?这在很大程度上取决于条件,可能非常简单或有点复杂。我建议您发布一个包含更具体细节的新问题,它的格式比评论更好。另外,根据您的要求,$project$$REMOVE 变量可能会对您有所帮助。
    • mainArray,但是一旦我创建了新问题,我将在此处通知新问题的链接
    猜你喜欢
    • 2020-10-29
    • 2020-01-24
    • 2020-04-23
    • 2015-03-10
    • 2021-08-13
    • 1970-01-01
    • 2018-09-10
    • 1970-01-01
    • 2021-02-13
    相关资源
    最近更新 更多