Vishal Sharma
Vishal Sharma

Reputation: 129

MongoDB- find document by id then group it with key


My Data-Structure looks like this:

[
  {
    "_id": "1",
    "title": "Yamaha",
    "data": "Sed ut perspiciatis",
    "type": "Bike"
  },
  {
    "_id": "2",
    "title": "Pulsar",
    "data": "Quis autem vel eum",
    "type": "Bike"
  },
  {
    "_id": "3",
    "title": "Tesla Model Y",
    "data": "because it is pleasure",
    "type": "Car"
  },
  {
    "_id": "4",
    "title": "Harley-Davidson",
    "data": "praising pain was born",
    "type": "Bike"
  },
  {
    "_id": "6",
    "title": "Mustang",
    "data": "non numquam eius",
    "type": "Car"
  },
  {
    "_id": "7",
    "title": "BMW",
    "data": "Man of Culture",
    "type": "Car"
  }
]

Now, From FrontEnd Users Can Search any of the item from database using their unique _id, Like this:

db.collection.find({_id: "3" })

Which returns the following:

[
  {
    "_id": "3",
    "data": "because it is pleasure",
    "title": "Tesla Model Y",
    "type": "Car"
  }
]

Question Part:

Now, Including the above-returned document, I also want to return those documents which have it's the matching type value.


My Questions means that; if the user is finding any document with their particular _id. let's suppose 3 then it should return the following:

Find the Item with their Unique _id and $group the type field Value

  [{
    "_id": "3",
    "title": "Tesla Model Y",
    "data": "because it is pleasure",
    "type": "Car"
  }
  {
    "_id": "6",
    "title": "Mustang",
    "data": "non numquam eius",
    "type": "Car"
  },
  {
    "_id": "7",
    "title": "BMW",
    "data": "Man of Culture",
    "type": "Car"
  }]

Is that possible to do? Is that possible to $group the document after finding By Id ?. I've tried Several Ways to make it but each of them is useless. Any Suggestions will be HelpFul for this complicated Requirement

:)

Upvotes: 3

Views: 736

Answers (2)

Andrey Popov
Andrey Popov

Reputation: 7510

You're basically mixing two separate queries:

  1. Get an item by ID - returns a single item
  2. Get a list of items, that have the same type as the type of the first item - returns a list of items

Because of the difference of the queries, there's no super straightforward way to do so. Surely you can use $aggregate to do the trick, but logic wise you'd still query quite a bit from the database, and you'd have to dig deeper to optimize it properly.

As long as you're not querying tens of millions of records, I'd suggest you do the two queries one after another, for the sake of simplicity.

Upvotes: -1

Takis
Takis

Reputation: 8695

Query

  • lookup with it self, join only with the type that the id=3 has.
  • empty join results => different type so they are filtered out

Test code here

db.collection.aggregate([
  {
    "$lookup": {
      "from": "collection",
      "let": {
        "type": "$type"
      },
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$and": [
                {
                  "$eq": [
                    "$_id",
                    "3"
                  ]
                },
                {
                  "$eq": [
                    "$$type",
                    "$type"
                  ]
                }
              ]
            }
          }
        }
      ],
      "as": "joined"
    }
  },
  {
    "$match": {
      "$expr": {
        "$ne": [
          "$joined",
          []
        ]
      }
    }
  },
  {
    "$unset": [
      "joined"
    ]
  }
])

Upvotes: 3

Related Questions