Get Number of elements with the same property MongoDB

Viewed 100

I have a kanban document structure of => Kanban,=>columns=>cards.properties

I need to determine the number of cards (looking on all my columns) that has the same property and write it down as a new property of my Card called "matchedCards"

for example, I have this Kanban:

enter image description here

Here I have 3 coconuts, 1 pinapple and 2 apples.

I'll leave my Demo Playground here:

Playground Kanban

I was trying something like 'matchedElements':{'$sum':"$$this.title"} on every card, but I don't know how to do it.

My final result should look like this:

enter image description here

3 Answers

You should also using db.collection.count() passing query inside a request of data

you could get the below result:

{
    "_id" : "Apple",
    "count" : 2
},
{
    "_id" : "Coconut",
    "count" : 3
},
{
    "_id" : "Pinapple",
    "count" : 1
}

by issuing the following query:

db.collection.aggregate([
    {
        "$match": {
            "_id": ObjectId("60ea230502e5ce273cf6e350")
        }
    },
    {
        $project: {
            _id: 0,
            _titles: {
                $reduce: {
                    input: "$columns.cards.title",
                    initialValue: [],
                    in: { $concatArrays: ["$$value", "$$this"] }
                }
            }
        }
    },
    {
        $unwind: "$_titles"
    },
    {
        $group: {
            _id: "$_titles",
            count: {
                $sum: 1
            }
        }
    }
])

but you'd be issuing a 2nd db query and will be matching the card titles and setting the counts client-side.

you can avoid a 2nd query by using $facet like so: https://mongoplayground.net/p/69XHSaZbHGK

that's the best i could come up with. maybe someone else would have a better/ more efficient approach.

You could use $unwind multiple times in your aggregate pipeline to get the desired result.

db.collection.aggregate([
  {
    "$match": {
      "_id": ObjectId("60ea230502e5ce273cf6e350")
    }
  },
  {
    $unwind: "$columns"
  },
  {
    $unwind: "$columns.cards"
  },
  {
    $group: {
      _id: "$columns.cards.title",
      "count": {
        "$sum": 1
      }
    }
  }
])

Playground link

This solution works for any number of elements in both of your nested arrays but be mindful that $unwind creates duplicates of your subdocuments and that will have performance tradeoffs.

Related