1

First document:

    {
    "_id" : 1,
    "array" : [ 
        {
            "userID" : 1,
            "name" : "name 1"
        }, 
        {
            "userID" : 2,
            "name" : "name 2"
        }, 
        {
            "userID" : 3,
            "name" : "name 3"
        }, 
        {
            "userID" : 6,
            "name" : "name 6"
        }
    ]
}

Second document:

    {
    "_id" : 2,
    "array" : [ 
        {
            "userID" : 1,
            "name" : "name 1"
        }, 
        {
            "userID" : 2,
            "name" : "name 2"
        }, 
        {
            "userID" : 3,
            "name" : "name 3"
        }, 
        {
            "userID" : 4,
            "name" : "name 4"
        }, 
        {
            "userID" : 5,
            "name" : "name 5"
        }
    ]
}

is there any way to get output like this:

   {    
    "array" : [  
        {  
            "userID" : 1,  
            "name" : "name 1" 
        },  
        {  
            "userID" : 2,  
            "name" : "name 2"  
        },   
        {  
            "userID" : 3,  
            "name" : "name 3"  
        }  
    ]  

    }  

I want to compare array fields of two documents and retrieve common elements in it. And compare array fields only by common 'userID'. Can we do it by $setIntersection? I need to check only two array fields at a time.

6
  • Will there always be 2 documents ? and is this (the 2 documents) an aggregation result ? Commented Jan 21, 2019 at 15:26
  • it is not an aggregation result. and i will take two documents by document._id Commented Jan 21, 2019 at 15:34
  • by First Document and Secoend Document do you mean, this are different different Objects right? or part of a SIngle Object? Commented Jan 21, 2019 at 15:37
  • you could also look into this answer , stackoverflow.com/questions/30646534/… Commented Jan 21, 2019 at 15:40
  • yes by first document and second document, these are two different objects Commented Jan 21, 2019 at 15:40

1 Answer 1

1

you can use $setIntersection

db.t67.aggregate([
    //{$match : {}} add filter criteria to filter documents
    {$group : {_id : null, array : {$push : "$array"}}},
    {$project : {_id :0, array : {$reduce : {input : "$array", initialValue : {$arrayElemAt : ["$array", 0]}, in : {$setIntersection : ["$$this", "$$value"]}}}}}
])

output

> db.t67.aggregate([
...     {$group : {_id : null, array : {$push : "$array"}}},
... {$project : {_id :0, array : {$reduce : {input : "$array", initialValue : {$arrayElemAt : ["$array", 0]}, in : {$setIntersection : ["$$this", "$$value"]}}}}}
... ])
{ "array" : [ { "userID" : 1, "name" : "name 1" }, { "userID" : 2, "name" : "name 2" }, { "userID" : 3, "name" : "name 3" } ] }

or $unwind and $group

db.t67.aggregate([
    // $match stages to filter 2 documents
    {$unwind : "$array"},
    {$group : {_id : "$array", count : {$sum : 1}}},
    {$match : {count : {$gt : 1}}},
    {$project : {count : 0}},
    {$group : {_id : null, array : {$push : "$_id"}}},
    {$project : {_id : 0}}
])

output

{ "_id" : null, "array" : [ { "userID" : 3, "name" : "name 3" }, { "userID" : 2, "name" : "name 2" }, { "userID" : 1, "name" : "name 1" } ] }
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for your reply.here we unwind array field of all documents, right? my collection has lot of documents like this. so i want to take only particular documents. not all documents. i can't take particular documents by passing document id from this query.
you need to add $match stage to filter the documents, in the answer I have commented the $match stage where you need to specify the filter criteria

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.