简体   繁体   中英

how to find unique values from array of object in mongoDB

i have following bson data in mongoDB

{name : "c1"
   arr : [
  {
     partyName : "p1",
     poNumber : "789",
  },
  {
     partyName : "p1",
     poNumber : "700",
  },
  {
     partyName : "p3",
     poNumber : "889",
  }
 ]
},

{name : "c2"
   arr : [
  {
     partyName : "p1",
     poNumber : "789",
  },
  {
     partyName : "p2",
     poNumber : "700",
  },
  {
     partyName : "p3",
     poNumber : "889",
  }
 ]
}

i want all unique values of partyName of name: "c1" object like [p1,p3]. i tried this

const unique = await User.distinct({name :"c1","createPurchaseOrder.partyName"})

(note:- User is my schema name ) but it gives error, i tried to search on web but cant find solution please help me with this

One option is using $reduce :

db.collection.aggregate([
  {$match: {name: "c1"}},
  {$project: {
      res: {
        $reduce: {
          input: "$arr",
          initialValue: [],
          in: {$setUnion: ["$$value", ["$$this.partyName"]]}
        }
      }
    }
  }
])

See how it works on the playground example

Query1

  • match for the document with name=c1
  • path to take the array with the partyName and union with the empty array to remove the duplicates
  • union => order can be lost in patyNames

Playmongo

aggregate(
[{"$match": {"name": {"$eq": "c1"}}},
 {"$project": 
   {"_id": 0, "parties-unique": {"$setUnion": ["$arr.partyName", []]}}}])

Query2

  • the above is fast and simple but loses the order of the names
  • if you want to keep the original order, you can use this instead
  • reduce and add on array only if element doesn't already exists

Playmongo

aggregate(
[{"$match": {"name": {"$eq": "c1"}}},
 {"$set": 
   {"parties-unique": 
     {"$reduce": 
       {"input": "$arr.partyName",
        "initialValue": [],
        "in": 
         {"$cond": 
           [{"$in": ["$$this", "$$value"]}, "$$value",
             {"$concatArrays": ["$$value", ["$$this"]]}]}}}}}])

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