Home > Back-end >  Filter and find documents which have more than one element in an array of objects which have same ke
Filter and find documents which have more than one element in an array of objects which have same ke

Time:06-03

A sample collection

[
  {
    "_id":"id1",
    "usersArray":[
      {
        "name":"user1Name",
        "type":1
      },
      {
        "name":"user2Name",
        "type":1
      },
      {
        "name":"user3Name",
        "type":2
      },
    ]
  },
  {
    "_id":"id2",
    "usersArray":[
      {
        "name":"user4Name",
        "type":1
      },
      {
        "name":"user5Name",
        "type":3
      },
      {
        "name":"user6Name",
        "type":2
      },
    ]
  },
  {
    "_id":"id3",
    "usersArray":[
      {
        "name":"user7Name",
        "type":1
      },
      {
        "name":"user8Name",
        "type":1
      },
      {
        "name":"user9Name",
        "type":2
      },
    ]
  },
]

What I need is a filter that will return the documents with _id id1 and id3 since they have more than 1 objects in usersArray which have key-value pairs "type": 1. It would be great if you could resolve this with just the filter.

CodePudding user response:

  1. $expr - Allow using aggregation operator.

    1.1. $gt - Filter the document with the result of 1.1.1 greater than 1.

    1.1.1. $size - Get the size of the result 1.1.1.1.

    1.1.1.1. $filter - Filter the document(s) with type: 1 in usersArray.

db.collection.find({
  $expr: {
    $gt: [
      {
        $size: {
          $filter: {
            input: "$usersArray",
            cond: {
              $eq: [
                "$$this.type",
                1
              ]
            }
          }
        }
      },
      1
    ]
  }
})

Sample Mongo Playground

CodePudding user response:

Query

  • make it set($union with empty), get the $size
  • get the original $size
  • if set size < original size => it contained duplicated type

*this is a way to do it not for type:1 duplicate only, this keeps documents that dont have duplicate same types, i am not sure what you need. (for example if type:2 is duplicated document wont pass the filter also)

Playmongo

aggregate(
[{"$match": 
   {"$expr": 
     {"$lt": 
       [{"$size": {"$setUnion": ["$usersArray.type", []]}},
        {"$size": "$usersArray.type"}]}}}])
  • Related