I’ve got a collection in MongoDB (6.0.2 community edition) called VS_Logs. In there is an array of objects looking a bit like this:
Lookups: [
{ REG: "ABC", .... // other stuff},
{ REG: "123", .... // other stuff} etc...
]
I’m trying to select the object from Lookups where REG = ABC.
I’ve tried this:
db.VS_Logs.findOne({"Lookups" : {$elemMatch: {"REG": "ABC" }}})
db.VS_Logs.find({"Lookups" : {$elemMatch: {"REG": "ABC" }}})
Both of those return all records.
I also tried:
db.VS_Logs.findOne({"Lookups.REG": "ABC"})
db.VS_Logs.find({"Lookups.REG": "ABC"})
Same result. What am I doing wrong?
2
Answers
db.VS_Logs.find({"Lookups.REG": "ABC"})
This query will retrieve all documents in the database where there is at least one object in the
Lookups
array whoseREG
property is set toAB
. It doesn’t matter if there are other objects in the array that don’t meet this condition.Instead of the entire document, if you are trying to select only those objects from
Lookups
array whereREG = ABC
. Try this,This aggregation pipeline will return the documents with an array called
matchingLookups
that only contains the objects from the Lookups array where theREG
property is set toABC
. The result would look somewhat like this,For Reference: https://mongoplayground.net/p/8C9Rz1rT0Zh
This doesn’t have to be done in aggregation. Particularly if the
matchingLookups
field is the only field you are interested in (or there are few others), then you can do this withfind()
instead if you prefer:Note that I’ve retained and simplified the query portion of the command. This will result in only documents that have matches being returned (as opposed to some documents coming back with empty lists). An index on that field would also allow the command to execute efficiently.
If you did want more fields then it would be better to use aggregation, swapping the
$project
stage for an$addFields
. Still probably best to prepend it with a$match
to filter the documents (prior to filtering the arrays within them) if needed.Playground demonstration here