【问题标题】:Using the results of a MongoDB db.collection.aggregate to exclude results from a db.collection.find使用 MongoDB db.collection.aggregate 的结果从 db.collection.find 中排除结果
【发布时间】:2018-09-07 06:13:28
【问题描述】:

我正在 AngularJS 和 Node 中编写一个 MongoDB 函数,我有一个集合,其中包含一个名为 documentId 的字段,该字段不是唯一的。我想在该集合中查找所有文档,其中特定文档的状态字段中没有一个包含单词 open,并且只包括所有状态为“关闭”或“取消”的文档。

例如:

_id: <val> , companyId : "CO-000001", documentId : "001", status:"closed", value:"123.45" _id: <val> , companyId : "CO-000001", documentId : "002", status:"closed", value:"323.67" _id: <val> , companyId : "CO-000001", documentId : "001", status:"open", value:"434.56" _id: <val> , companyId : "CO-000001", documentId : "002", status:"canceled", value:"523.16"

我希望我的结果仅包含 documentId 002 而不是 documentId 001,因为 documentId 为 001 的文档之一包含打开状态。但由于 documentId 为 002 的所有文档的状态为已关闭或已取消,因此我想将其包含在结果中。

我可以使用以下命令从 db.collection.find() 中获取要排除的文档的汇总...

db.tickets.aggregate(
[
    { 
        "$match" : {
            "companyId" : "CO-000001", 
            "$and" : [
                {
                    "status" : {
                        "$in" : [
                            "open","on hold" 
                        ]
                    }
                }
            ]
        }
    }, 
    { 
        "$group" : {
            "_id" : null, 
            "uniqueValues" : {
                "$addToSet" : "$documentId"
            }
        }
    }
], 
{ 
    "allowDiskUse" : false
}

);

但现在我想在查询时使用聚合中的数组结果...

db.tickets.find("companyId":"CO-000001", $and:[{documentId:{$nin:[<results from aggregation>]}}])

有没有办法在另一个查询中使用聚合结果?或者有没有办法在聚合中完成所有这些操作?

【问题讨论】:

  • 在聚合本身中使用 $lookup 来加入表并获得结果。
  • $lookup 将包含结果中的文档。我想排除它们。
  • 随心所欲地投影
  • 我认为你没有花时间去理解这个问题。投影允许您指定要返回的字段。我不希望排除字段,而是排除整个文档。我的印象是您不了解问题集。

标签: angularjs node.js mongodb


【解决方案1】:

根据您的需要更改投影。观察我后来如何使用分组和匹配阶段来获取所需的数据。希望这能解决您的问题。

 db.tickets.aggregate(
    [
        { 
            "$match" : {
                "companyId" : "CO-000001"
            }
        }, 
        { 
            "$group" : {
                "_id" : "$documentId", 
                "status" :{
                "$addToSet" : "$status"
                }
            }
        },
        {
            $match:{ status:{$nin:["open","on hold"]} }
        },{
        $lookup:{  
             from:"tickets",
             as: "final",
             localField: "_id",
             foreignField: "documentId",
          }
        },
        {
            $project :{
                _id:0,
                final:1
            }
        }
    ], 
    { 
        "allowDiskUse" : false
    }
    ).pretty();

【讨论】:

  • 这太棒了!太感谢了。我只需要进行一次调整...在查找之前,我必须先按 uniqueValues 进行分组。但除此之外,这正是我所需要的。可能我没看懂你在上面的cmets中说什么,但是通过例子就清楚了。
  • 我能知道你做了什么调整吗?
  • 只是在查找之前按唯一值添加分组。
  • 有点困惑,希望我的回答能解决你的问题。
  • 当我只使用您的解决方案进行查找时,它返回每个文档多个条目。我只需要一个,因此通过在进行查找之前按 documentId 上的 uniqueValues 分组,每个 documentId 只得到一个符合条件的文档结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
  • 2017-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多