所以我在聚合管道的某个阶段,我的文档目前看起来像这样:
{
{ a: 'ObjectIDA', b: 'ObjectIDB' },
{ a: 'ObjectIDB', b: 'ObjectIDA' },
{ a: 'ObjectIDC', b: 'ObjectIDB' },
{ a: 'ObjectIDA', b: 'ObjectIDC' },
...
}
我如何过滤这些文档以只获得唯一的objectid对?
如果"唯一对"仅指"ObjectA"one_answers"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" ] }
所以这里的关键点是:
- 获取元素到数组
- 将数组排序为一致的顺序
- 一致排序数组上的组
使用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,插入与"you"完全相同的信息:
db.collection.drop();
db.collection.insert([
{ a: 'ObjectIDA', b: 'ObjectIDB' },
{ a: 'ObjectIDB', b: 'ObjectIDA' },
{ a: 'ObjectIDC', b: 'ObjectIDB' },
{ a: 'ObjectIDA', b: 'ObjectIDC' }
]);
现在运行聚合语句"exactly",正如我所呈现的那样,并看到我之前发布的相同结果:
{ "_id" : [ "ObjectIDA", "ObjectIDB" ] }
{ "_id" : [ "ObjectIDB", "ObjectIDC" ] }
{ "_id" : [ "ObjectIDA", "ObjectIDC" ] }
删除重复出现的"ObjectIDA"one_answers"ObjectIDB"以相反的顺序。