使用集合B中的信息过滤集合A中的文档 - 如何?

时间:2014-07-14 12:26:25

标签: mongodb mongodb-shell

让我们假设一个集合A,其中包含以下结构的文档:

{_id: N},N为正整数

第二个收集B,包含以下类型的文件:

{_id: M, ids: [n1,n2,...]} n1,n2,...是正整数

B中的文件有效地定义了集合A中的文档集。

这意味着集合A中有两种类型的文档:

  • 其_id值至少包含在集合B中文档的一个ids-array中的文档
  • 以及_id未包含在集合B 的任何ids-array中的那些

现在我不知道如何使用MongoDB shell表达式完成以下任务:

我想从集合A中删除所有未包含在集合B中任何文档的ids-array中的文档。


我的直观方法是将所有id-arrays转换为带有聚合的集合,然后使用这个新数组在remove-method中编写查询 - 但这似乎不起作用。


我尝试了很多东西 - 这里有一个:

> db.A.find()
{ "_id" : 1 }
{ "_id" : 2 }
{ "_id" : 3 }
{ "_id" : 4 }
{ "_id" : 5 }
{ "_id" : 6 }
{ "_id" : 7 }
{ "_id" : 8 }

> db.B.find()
{ "_id" : ObjectId("53c4c9ae55cdc092a772cb15"), "ids" : [ 1, 2, 3 ] }
{ "_id" : ObjectId("53c4c9b855cdc092a772cb16"), "ids" : [ 3, 4, 5 ] }

> var ids = db.B.aggregate({$unwind:"$ids"},{$group:{_id:0,x:{$addToSet:"$ids"}}})
{ "_id" : 0, "x" : [ 5, 4, 3, 2, 1 ] }

> ids
{ "_id" : 0, "x" : [ 5, 4, 3, 2, 1 ] }

> db.A.find({_id:{$nin:ids.x}})
error: {
    "$err" : "Can't canonicalize query: BadValue $nin needs an array",
    "code" : 17287
}

1 个答案:

答案 0 :(得分:1)

将您的ids声明行替换为:

var ids = db.B.aggregate(
    {$unwind:"$ids"},
    {$group:{_id:0,x:{$addToSet:"$ids"}}}
).next();

实际上$unwind会返回一个光标......