使用MongoDB聚合获取唯一的ObjectIds对

时间:2015-07-15 02:27:41

标签: mongodb mongodb-query aggregation-framework

所以我正处于聚合管道的某个阶段,我的文档目前看起来像这样:

{
    { a: 'ObjectIDA', b: 'ObjectIDB' },
    { a: 'ObjectIDB', b: 'ObjectIDA' },
    { a: 'ObjectIDC', b: 'ObjectIDB' },
    { a: 'ObjectIDA', b: 'ObjectIDC' },
    ...
}

如何过滤这些文档以仅获取唯一的ObjectIds对?

1 个答案:

答案 0 :(得分:1)

如果通过“唯一对”,您只是指任何顺序的“ObjectA”和“ObjectB”,那么您需要执行以下操作:

db.collection.aggregate([
    { "$project": {
       "combined": {
           "$map": {
               "input": { "$literal": ["A","B"] },
               "as": "i",
               "in": { "$cond": [
                   { "$eq": [ "$$i", "A" ] },
                   "$a",
                   "$b"
               ]}
           }
       }
    }},
    { "$unwind": "$combined" },
    { "$sort": { "_id": 1, "combined": 1 } },
    { "$group": {
        "_id": "$_id",
        "combined": { "$push": "$combined" }
    }},
    { "$group": {
        "_id": "$combined"
    }}
])

产生:

{ "_id" : [ "ObjectIDA", "ObjectIDB" ] }
{ "_id" : [ "ObjectIDB", "ObjectIDC" ] }
{ "_id" : [ "ObjectIDA", "ObjectIDC" ] }

所以关键点是:

  1. 将元素放入数组
  2. 按照一致的顺序对文件进行排序
  3. 对一致排列的数组进行分组
  4. 它使用MongoDB 2.6引入的运算符,但您可以对早期版本执行相同的操作:

    db.collection.aggregate([
        { "$project": {
            "a": 1,
            "b": 1,
            "type": { "$const": [ "A", "B" ] }
        }},
        { "$unwind": "$type" },
        { "$group": {
            "_id": "$_id",
            "combined": {
                "$push": {
                    "$cond": [
                        { "$eq": [ "$type", "A" ] },
                        "$a",
                        "$b"
                    ]
                }
            }
        }},
        { "$unwind": "$combined" },
        { "$sort": { "_id": 1, "combined": 1 } },
        { "$group": {
            "_id": "$_id",
            "combined": { "$push": "$combined" }
        }},
        { "$group": {
            "_id": "$combined"
        }}
    ])
    

    打开一个shell并完全按照“你”的方式插入信息:

    db.collection.drop();
    db.collection.insert([
        { a: 'ObjectIDA', b: 'ObjectIDB' },
        { a: 'ObjectIDB', b: 'ObjectIDA' },
        { a: 'ObjectIDC', b: 'ObjectIDB' },
        { a: 'ObjectIDA', b: 'ObjectIDC' }
    ]);
    

    现在运行聚合语句“完全”,因为我提出它,并看到我之前发布的相同结果:

    { "_id" : [ "ObjectIDA", "ObjectIDB" ] }
    { "_id" : [ "ObjectIDB", "ObjectIDC" ] }
    { "_id" : [ "ObjectIDA", "ObjectIDC" ] }
    

    以相反的顺序删除“ObjectIDA”和“ObjectIDB”的重复出现。

    一致的排序就是这就是它。

相关问题