简体   繁体   中英

Mongodb aggregate by using input array

I am struggling to create an aggregate query for my MongoDB database.

here is my input array

recipients = [1,2,7]

here is my database collection

{
    "chapter": 1,
    "targets": [
      {
        type: 'user',
        recipient: 1
      }
    ]
  },
  {
    "chapter": 1,
    "targets": [
      {
        type: 'user',
        recipient: 2
      }
    ]
  },
  {
    "chapter": 2,
    "targets": [
      {
        type: 'user',
        recipient: 3
      }
    ]
  },
  {
    "chapter": 3,
    "targets": [
      {
        type: 'user',
        recipient: 4
      }
    ]
  },

the desired output

should be [] because 7 doesn't exist in targets.recipient in the collection

here is what I've tried so far

db.collection.aggregate([
  {
      $match: {
        'targets.recipient': { $in: recipients },
      },
    }
])

Any suggestions, thank you.

The way $in works is that it returns the document if there's any match between it's value and the array you're passing as a parameter. It looks like in your case you can use $in for initial filtering but then you want to return the result only if the result set contains all the values from the input array. In order to achieve it you can use $group to get all matching results and then apply $all :

db.collection.aggregate([
    {
        $match: { "targets.recipient": { $in: [1,2,7] } }
    },
    {
        $group: {
            _id: null,
            docs: { $push: "$$ROOT" }
        }
    },
    {
        $match: { "docs.targets.recipient": { $all: [1,2,7] } }
    }
])

Mongo Playground

// only matched documents will be shown.
> db.targets.aggregate([ {$match:{"targets.recipient":{$in:[1,2,7]}}}, {$project:{chapter:1,targets:1}} ]).pretty();
{
        "_id" : ObjectId("5f5de14c598d922a1e6eff4d"),
        "chapter" : 1,
        "targets" : [
                {
                        "type" : "user",
                        "recipient" : 1
                }
        ]
}
{
        "_id" : ObjectId("5f5de14c598d922a1e6eff4e"),
        "chapter" : 1,
        "targets" : [
                {
                        "type" : "user",
                        "recipient" : 2
                }
        ]
}
>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM