-1

Let's assume a collection A with documents of following structure:

{_id: N} with N being a positive integer

And a second collection B with documents of the following kind:

{_id: M, ids: [n1,n2,...]} with n1,n2,... being a positive integers

The documents in B are effectively defining sets of documents from collection A.

That means there are two types of documents in collection A:

  • documents whose _id value is contained in at least one ids-array of a document in collection B
  • and those whose _id is not contained in any ids-array of a doc in collection B

Now I have no idea how to get the following task done using a MongoDB shell expression:

I would like to remove all documents from collection A which are not contained in any ids-array of a document in collection B.


My intuitive approach would be to turn all ids-arrays into a set with aggregate and then use this new array for composing a query within a remove-method - but this doesn't seem to work.


I tried multiple things - here's one:

> 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
}
Raffael
  • 19,547
  • 15
  • 82
  • 160

1 Answers1

1

Replace your ids declaration line with:

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

Actually $unwind returns a cursor...

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
dgiugg
  • 1,294
  • 14
  • 23