Is there any way for Mongo to return some indication (flag, field, etc..) for if an input in a $in
does not match any docs
?
Please see my Mongo Playgrond
That successfully just returns all odd documents.
How can I have some indication that the evens were not found?
I'd like to do this within Mongo itself. I get I can iterate through the results in JS
and perform a diff
.
Fwiw, I this $in
will actually be the first stage of a $match
in an aggregate
. So maybe I can use something like addFields
for the unmatches.
Thanks!
So my desired output could be that each negative match still gets a returning document..but with a new property found:false
like the following. So..in my example, evens #s are not founds and it'd be cool to see something like..
{
"_id": ObjectId("5a934e000102030405100006"),
"key": 2,
"found": false
},
{
"_id": ObjectId("5a934e000102230405000006"),
"key": 4,
"found": false
},
{
"_id": ObjectId("5a934e000122030405000006"),
"key": 6,
"found": false
}
Maybe, it'd be cleaner to put found
as true for all positive matches as well.
Or...maybe return an subarray of the unmatches (that could be cleaner in post-processing)
CodePudding user response:
There is no straight way to do this in MongoDB, You can try aggregation query to handle custom requirements,
Here I have added an aggregation query to achieve your requirement, but I am not sure what is your exact data,
Input:
[
{ "key": 1 },
{ "key": 2 },
{ "key": 3 },
{ "key": 4 },
{ "key": 50 },
{ "key": 6 },
{ "key": 7 }
]
$match
your$in
condition$facet
to separate results and not found numbersresult
key is to get your final document resultsnotFound
is to find the not found keys$group
by null and get unique keys from result using$addToSet
$setDifference
to get the difference of two arrays, first is your input and second available result numbers$project
to show required fields
db.collection.aggregate([
{
$match: {
key: {
$in: [1, 3, 5, 7]
}
}
},
{
$facet: {
result: [],
notFound: [
{
$group: {
_id: null,
key: { $addToSet: "$key" }
}
},
{
$project: {
key: {
$setDifference: [[1, 3, 5, 7], "$key"]
}
}
}
]
}
}
])
Result:
[
{
"notFound": [
{ "key": [5] }
],
"result": [
{ "key": 1 },
{ "key": 3 },
{ "key": 7 }
]
}
]
The second approach, as per your expected result sample,
$addFields
to add new fieldfound
$in
to checkkey
has value in the provided array, if yes then return true otherwise false
db.collection.aggregate([
{
$addFields: {
found: {
$in: ["$key", [1, 3, 5, 7]]
}
}
}
])
Result:
[
{ "key": 1, "found": true },
{ "key": 2, "found": false },
{ "key": 3, "found": true },
{ "key": 4, "found": false },
{ "key": 50,"found": false },
{ "key": 6, "found": false },
{ "key": 7, "found": true }
]