Mongo Query返回数组中的常用值

时间:2017-02-17 16:15:21

标签: mongodb mongodb-query aggregation-framework

我需要一个Mongo Query来返回数组中存在的常用值。 因此,如果匹配中有4个文档,那么如果这些文档存在于所有4个文档中,则返回值

假设我的db

中有以下文档

Mongo文件


    {
    "id":"0",
    "merchants":["1","2"]
    }

    {
    "id":"1",
    "merchants":["1","2","4"]
    }

    {
    "id":"2",
    "merchants":["4","5"]
    }

输入:ID列表

(i)输入id为“0”和“1”

然后它应该返回我的商家:[“1”,“2”]因为两者都出现在ID为“0”的文件中。 id“1”

(ii)ID为“1”和“2”的输入 然后它应该返回我的商家:[“4”],因为它很常见,并且存在于ID为“1”的两个文件中。 id“2”

(iii)id为“0”和“2”的输入 应该返回空商家:[]这两个文件之间没有共同的商家

3 个答案:

答案 0 :(得分:2)

您可以尝试以下聚合。

db.collection.aggregate(
   {$match:{id: {$in: ["1", "2"]}}},
   {$group:{_id:null, first:{$first:"$merchants"}, second:{$last:"$merchants"}}},
   {$project: {commonToBoth: {$setIntersection: ["$first", "$second"]}, _id: 0 } }
)   

答案 1 :(得分:1)

假设您有一个函数query为您执行所需的数据库查询,并且您将使用idsToMatch调用该函数,const query = (idsToMatch) => { db.collectionName.aggregate([ { $match: { id: {$in: idsToMatch} } }, { $unwind: "$merchants" }, { $group: { _id: { id: "$id", data: "$merchants" } } }, { $group: { _id: "$_id.data", count: {$sum: 1} } }, { $match: { count: { $gte: idsToMatch.length } } }, { $group: { _id: 0, result: {$push: "$_id" } } }, { $project: { _id: 0, result: "$result" } } ]) 是一个包含您要匹配的所有元素的数组。我在这里使用JS作为驱动程序语言,用你正在使用的任何东西替换它。

以下代码是动态的,适用于您输入的任意数量的ID:

$group
  1. 第一个merchants声明是为了确保您没有 重复文档中的任何merchants属性。如果 你确定在你的个人文件中你没有任何东西 $match的重复值,您无需包含它。
  2. 实际工作只发生在第二$group阶段。最后两个 阶段($projectaggregate([ { $match: { id: {$in: idsToMatch} } }, { $unwind: "$merchants" }, { $group: { _id: "merchants", count: {$sum: 1} } }, { $match: { count: { $gte: idsToMatch.length } } } ]) )只是为了美化结果, 你可以选择不使用它们,而是使用你的语言 选择以您想要的形式转换它
  3. 假设您希望按照上面给出的点减少阶段,实际代码将减少到:

    _id

    您所需的值将位于结果数组的每个元素的{{1}}属性中。

答案 2 :(得分:0)

@ jgr0提供的答案在某种程度上是正确的。唯一的错误是中间匹配操作

(i)因此,如果输入ID是" 1" &安培; " 0"然后查询变为


     aggregate([
            {"$match":{"id":{"$in":["1","0"]}}},
            {"$unwind":"$merchants"},
            {"$group":{"_id":"$merchants","count":{"$sum":1}}},
            {"$match":{"count":{"$eq":2}}},
            {"$group":{"_id":null,"merchants":{"$push":"$_id"}}},
            {"$project":{"_id":0,"merchants":1}} 
            ])

(ii)因此,如果输入ID为" 1"," 0" &安培; " 2"然后查询变为


    aggregate([
        {"$match":{"id":{"$in":["1","0", "2"]}}},
        {"$unwind":"$merchants"},
        {"$group":{"_id":"$merchants","count":{"$sum":1}}},
        {"$match":{"count":{"$eq":3}}},
        {"$group":{"_id":null,"merchants":{"$push":"$_id"}}},
        {"$project":{"_id":0,"merchants":1}} 
        ])

中间匹配操作应该是输入中的ID数。因此,如果(i)它是2,而在情况(2)中它是3。