Kleber
Kleber

Reputation: 1065

Is there a way to merge two arrays into one single array in MongoDB?

I'm kinda new in MongoDB and I'm having trouble to achieve a certain task. I'll try to explain it.

Here is my collection:

'workers': [
    {
        _id: ObjectId(...),
        name: 'John',
        skills: [
            { id: ObjectId('111'), value: 2 },
            { id: ObjectId('222'), value: 3 },
            { id: ObjectId('333'), value: 4 },
        ]
    },
    {
        _id: ObjectId(...),
        name: 'Mary',
        skills: [
            { id: ObjectId('222'), value: 5 },
            { id: ObjectId('333'), value: 2 },
            { id: ObjectId('444'), value: 3 },
        ]
    },
    ...
]

What I'm trying to achieve is something like this:

result: [
    allSkills: [
        { id: ObjectId('111'), value: 2 },
        { id: ObjectId('222'), value: 5 },
        { id: ObjectId('333'), value: 4 },
        { id: ObjectId('444'), value: 3 }
    ]
]

My result should be a single array with all skills inside the workers collection (eventually I'll filter them).

In the example, I show my final result, with only unique values and the greater value for each skill, but what I'm trying to achieve here is just merge all skills arrays into a single allSkills array. For now, what I'm getting is a list of documents, each with its skills array.

Thanks in advance.

Upvotes: 0

Views: 832

Answers (2)

Kleber
Kleber

Reputation: 1065

I accepted Sebastián Espinosa's answer since it answered my question. But just for the record, I ended up using another solution and I'm putting here to future reference:

db.workers.aggregate([
    { $unwind: "$skills" },
    {
        $group: {
            _id: '$skills.id',
            value: { $max: '$skills.value' }
        }
    }
])

Which produced the result:

result: [
    { id: ObjectId('111'), value: 2 },
    { id: ObjectId('222'), value: 5 },
    { id: ObjectId('333'), value: 4 },
    { id: ObjectId('444'), value: 3 }
]

The treasure here lies on the $unwind operator, which helped to actually merge the skills arrays.

The reason I didn't use the marked answer was because I couldn't develop it to the final result I was looking for, but, as I said, it totally answered my original question.

Upvotes: 1

Sebastián Espinosa
Sebastián Espinosa

Reputation: 2133

Something like this?:

db.collection.distinct('skills');

distinct api docs here!

also, if you want to get only a prop of the skill object, like for example "value", you can do this:

db.collection.distinct('skills.value');

hope it helps.

Upvotes: 3

Related Questions