I want to get an array of documents of matching value for a field from same collection

28 Views Asked by At

Below is my collection:

[
    {
        "_id": {
            "$oid": "6427c43b0db930a08abc8f80"
        },
        "propertyType": "Flat",
        "entity": "1",
        "size": "28*32",
        "area": "896",
        "rate": "3570",
        "addedBy": "6427ae52533858bad362fc6f"
    },
    {
        "_id": {
            "$oid": "6427cda508bc3cc01c36fcf1"
        },
        "propertyType": "Banglow",
        "entity": "1",
        "size": "80*50",
        "area": "4000",
        "rate": "5600",
        "addedBy": "6427ae52533858bad362fc6f"
    },
    {
        "_id": {
            "$oid": "6427dbc3a39c42b59d95c364"
        },
        "propertyType": "Flat",
        "entity": "1",
        "size": "32*32",
        "area": "1024",
        "rate": "3500",
        "addedBy": "6427dd2aa39c42b59d95c368"
    },
    {
        "_id": {
            "$oid": "6427dbe1a39c42b59d95c365"
        },
        "propertyType": "Banglow",
        "entity": "6",
        "size": "43*100",
        "area": "4300",
        "rate": "6130",
        "addedBy": "6427ae52533858bad362fc6f"
    },
    {
        "_id": {
            "$oid": "6427dbc3a39c42b59d95c363"
        },
        "propertyType": "Banglow",
        "entity": "1",
        "size": "80*40",
        "area": "3200",
        "rate": "4820",
        "addedBy": "6427dd2aa39c42b59d95c368"
    }
]

I want below output :

[
    {
        "addedBy": "6427ae52533858bad362fc6f",
        "properties": {
            "flats": [
                {
                    "_id": {
                        "$oid": "6427c43b0db930a08abc8f80"
                    },
                    "propertyType": "Flat",
                    "entity": "1",
                    "size": "28*32",
                    "area": "896",
                    "rate": "3570",
                    "addedBy": "6427ae52533858bad362fc6f"
                }
            ],
            "banglows": [
                {
                    "_id": {
                        "$oid": "6427cda508bc3cc01c36fcf1"
                    },
                    "propertyType": "Banglow",
                    "entity": "1",
                    "size": "80*50",
                    "area": "4000",
                    "rate": "5600",
                    "addedBy": "6427ae52533858bad362fc6f"
                },
                {
                    "_id": {
                        "$oid": "6427dbe1a39c42b59d95c365"
                    },
                    "propertyType": "Banglow",
                    "entity": "6",
                    "size": "43*100",
                    "area": "4300",
                    "rate": "6130",
                    "addedBy": "6427ae52533858bad362fc6f"
                }
            ]
        }
    },
    {
        "addedBy": "6427dd2aa39c42b59d95c368",
        "properties": {
            "flats": [
                {
                    "_id": {
                        "$oid": "6427dbc3a39c42b59d95c364"
                    },
                    "propertyType": "Flat",
                    "entity": "1",
                    "size": "32*32",
                    "area": "1024",
                    "rate": "3500",
                    "addedBy": "6427dd2aa39c42b59d95c368"
                }
            ],
            "banglows": [
                {
                    "_id": {
                        "$oid": "6427dbc3a39c42b59d95c363"
                    },
                    "propertyType": "Banglow",
                    "entity": "1",
                    "size": "80*40",
                    "area": "3200",
                    "rate": "4820",
                    "addedBy": "6427dd2aa39c42b59d95c368"
                }
            ]
        }
    }
]

I want to have a list of all documents for same value of addedBy the documents grouped by propertyType. As to showcase a summary of type of properties addedBy each user. All the records are in same collection and I want output from that collection only.

I have tried below flow :

[
  {
    '$lookup': {
      'from': 'properties', 
      'localField': 'addedBy', 
      'foreignField': 'addedBy', 
      'as': 'user'
    }
  }, {
    '$project': {
      'user': 1, 
      '_id': 0
    }
  }
]
1

There are 1 best solutions below

0
nimrod serok On BEST ANSWER

Essentially you want to group the documents of the collection, so each document will appear once on its relevant group (propertyType and addedBy). One option is to $group twice and use $arrayToObject:

db.properties.aggregate([
  {$group: {
      _id: {addedBy: "$addedBy", properties: "$propertyType"},
      v: {$push: "$$ROOT"},
      k: {$first: "$propertyType"}
  }},
  {$group: {
      _id: "$_id.addedBy",
      properties: {$push: {k: "$k", v: "$v"}}
  }},
  {$project: {
      addedBy: "$_id", _id: 0,
      properties: {$arrayToObject: "$properties"}
  }}
])

See how it works on the playground example