-1

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

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

Comments

0

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"]]}]}}}}}])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.