Home > OS >  How to show only one of the multiple documents in mongoDB?
How to show only one of the multiple documents in mongoDB?

Time:11-30

I'm trying to join or call only one document from multiple documents that can be repeated, all this for a unique identifier, in this case code, which is a numerical value.

[
    {
      "_id": "6386b0e114fe6aee844af06e",
      "transfer": {
        "code": 2,
        "author": {
          "created_at": "2022-11-30T01:29:43.308Z",
          "created_by": "userId",
          "observation": "It is a long established fact that a reader will be distracted"
        },
        "output": {
          "type": "Transfer out",
          "quantity": 3,
          "to": {
            "warehouse": "6376d84a4587772c3b2d7175",
            "warehouse_location": "637d6e218006a7e9609aaf2f",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        },
        "entry": {
          "type": "Transfer in",
          "quantity": 3,
          "from": {
            "warehouse": "6376d6c5716fea2e60c491c6",
            "warehouse_location": "637d6e1b8006a7e9609aaf2e",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        }
      }
    },
    {
      "_id": "6386b13e14fe6aee844af06f",
      "transfer": {
        "code": 2,
        "author": {
          "created_at": "2022-11-30T01:29:43.308Z",
          "created_by": "userId",
          "observation": "It is a long established fact that a reader will be distracted"
        },
        "output": {
          "type": "Transfer out",
          "quantity": 3,
          "to": {
            "warehouse": "6376d84a4587772c3b2d7175",
            "warehouse_location": "637d6e218006a7e9609aaf2f",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        },
        "entry": {
          "type": "Transfer in",
          "quantity": 3,
          "from": {
            "warehouse": "6376d6c5716fea2e60c491c6",
            "warehouse_location": "637d6e1b8006a7e9609aaf2e",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        }
      }
    },
    {
      "_id": "6386b0e114fe6aee844af06e",
      "transfer": {
        "code": 1,
        "author": {
          "created_at": "2022-11-30T01:27:52.003Z",
          "created_by": "userId",
          "observation": "It is a long established fact that a reader will be distracted"
        },
        "output": {
          "type": "Transfer out",
          "quantity": 1,
          "to": {
            "warehouse": "6376d84a4587772c3b2d7175",
            "warehouse_location": "637d6e218006a7e9609aaf2f",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        },
        "entry": {
          "type": "Transfer in",
          "quantity": 1,
          "from": {
            "warehouse": "6376d6c5716fea2e60c491c6",
            "warehouse_location": "637d6e1b8006a7e9609aaf2e",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        }
      }
    },
    {
      "_id": "6386b13e14fe6aee844af06f",
      "transfer": {
        "code": 1,
        "author": {
          "created_at": "2022-11-30T01:27:52.003Z",
          "created_by": "userId",
          "observation": "It is a long established fact that a reader will be distracted"
        },
        "output": {
          "type": "Transfer out",
          "quantity": 1,
          "to": {
            "warehouse": "6376d84a4587772c3b2d7175",
            "warehouse_location": "637d6e218006a7e9609aaf2f",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        },
        "entry": {
          "type": "Transfer in",
          "quantity": 1,
          "from": {
            "warehouse": "6376d6c5716fea2e60c491c6",
            "warehouse_location": "637d6e1b8006a7e9609aaf2e",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        }
      }
    }
  ]

In this case I need only two of the documents code: 1 and code:2 to be displayed, something like this:

[
    {
      "_id": "6386b0e114fe6aee844af06e",
      "transfer": {
        "code": 2,
        "author": {
          "created_at": "2022-11-30T01:29:43.308Z",
          "created_by": "userId",
          "observation": "It is a long established fact that a reader will be distracted"
        },
        "output": {
          "type": "Transfer out",
          "quantity": 3,
          "to": {
            "warehouse": "6376d84a4587772c3b2d7175",
            "warehouse_location": "637d6e218006a7e9609aaf2f",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        },
        "entry": {
          "type": "Transfer in",
          "quantity": 3,
          "from": {
            "warehouse": "6376d6c5716fea2e60c491c6",
            "warehouse_location": "637d6e1b8006a7e9609aaf2e",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        }
      }
    },
    {
      "_id": "6386b13e14fe6aee844af06f",
      "transfer": {
        "code": 1,
        "author": {
          "created_at": "2022-11-30T01:27:52.003Z",
          "created_by": "userId",
          "observation": "It is a long established fact that a reader will be distracted"
        },
        "output": {
          "type": "Transfer out",
          "quantity": 1,
          "to": {
            "warehouse": "6376d84a4587772c3b2d7175",
            "warehouse_location": "637d6e218006a7e9609aaf2f",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        },
        "entry": {
          "type": "Transfer in",
          "quantity": 1,
          "from": {
            "warehouse": "6376d6c5716fea2e60c491c6",
            "warehouse_location": "637d6e1b8006a7e9609aaf2e",
            "expiration_date": "2024-01-03",
            "production_lot": "LOT0544522",
            "product": "6366a7d99795c333b24f0981"
          }
        }
      }
    }
  ]

The original nomenclature of the object corresponds to the following,

[
    {
      "product":"6366a7d99795c333b24f0981",
      "warehouse": "6376d6c5716fea2e60c491c6",
      "warehouse_location": "637d6e1b8006a7e9609aaf2e",
      "quantity": 100,
      "movements": [
        {
          "entries": [...],
          "outputs": [...],
          "transfers": [...]
        }
      ]
    }
  ]

For this reason, what I do is get to the level of each type of movement, be it transfer, inventory inputs or outputs, and I do it as follows:

return this.connect().then((db) => {
      return (
        db
          .collection(collection)
          // The following aggregation uses the $unwind stage to output a
          // document for each element in the movements.outputs array
          .aggregate([
            // Stage 1
            { $unwind: '$movements' },
            // Stage 2
            { $unwind: '$movements.transfers' },
            // Group by code field
            {
              $group: {
                code: ...,
              },
            },
          ])
          // The following project only returns the movements.transfers object
          .project({
            transfer: '$movements.transfers',
          })
          .sort({ 'transfer.code': -1 })
          .toArray()
      );
    });

I have tried to use merge or group but have not been able to do what I expect based on the code parameter. Any other way to achieve this?

CodePudding user response:

Use Sample https://www.mongodb.com/docs/manual/reference/operator/aggregation/sample/

Add this to your query

aggregate(
   [ { $sample: { size: 1 } } ]
)

CodePudding user response:

One option is two add to steps to your aggregation pipeline:

db.collection.aggregate([
  {$group: {_id: "$transfer.code", data: {$first: "$$ROOT"}}},
  {$replaceRoot: {newRoot: "$data"}}
])

See how it works on the playground example

But there is no much point in $unwind and then $group again just after. if you share a simplified version of your documents before the $unwind steps, and the requested result for them, we can see how to optimize this query before the current step.

  • Related