文档子集的唯一字段值

时间:2017-12-29 16:23:38

标签: mongodb

这是一个MongoDB查询和聚合难题。打一些样本记录:

# Document 1
{
  items: [
    {
      type: "X",
      id: 123
    },
    {
      type: "Y",
      id: 456
    }
  ]
}

# Document 2
{
  items: [
    {
      type: "A",
      id: 789
    },
    {
      type: "B",
      id: 321
    }
  ]
}

# Document 3
{
  items: [
    {
      type: "P",
      id: 987
    },
    {
      type: "X",
      id: 654
    }
  ]
}

# Document 4
{
  items: [
    {
      type: "Q",
      id: 246
    },
    {
      type: "X",
      id: 654
    }
  ]
}

我的目标是找到包含id的文档的所有不同type: X值,其中id是与id元素相关联的type: X

例如,在上面,我希望我的结果是:

[ 123, 654 ]

这些是与id相关联的type: X字段的唯一值。

2 个答案:

答案 0 :(得分:2)

您可以从unwinding商品开始。然后,您可以按类型过滤掉。在最后一步中,您可以使用$addToSet运算符来消除重复。

db.collection.aggregate([
  { $unwind: "$items" },
  { $match: { "items.type": "X" } },
  { 
    $group: {
      _id: 1,
      ids: { $addToSet: "$items.id" }
    }
  }
])

使用_id: 1进行分组意味着我按任何方式进行分组:我知道所有内容都应该只是一个组的一部分,但我需要使用$ addToSet。

答案 1 :(得分:2)

您可以使用以下聚合来获取唯一ID。

查询$filters类型为输入类型的项目,然后$arrayElemAt投影匹配项目,$let提取id字段。

$group所有$addToSet个id值的项目都会输出唯一值。

db.collection_name.aggregate([{"$group":{
  "_id":null,
  "ids":{
    "$addToSet":{
      "$let":{
        "vars":{
          "obj":{
            "$arrayElemAt":[
              {"$filter":{
                "input":"$items",
                "cond":{"$eq":["$$this.type","X"]}
              }},
              0
            ]
          }
        },
        "in":"$$obj.id"
      }
    }
  }
}}])