Given multiples documents containing a key named userId
, where this key is always an object:
{
"_id": {
"$oid": "22fc6b11a0ff111d598b114f"
},
"userId": {
"KEY1" : ["..."],
"KEY2" : ["..."],
"KEY3" : ["..."],
"KEY4" : ["..."]
},
}
It will always contain 4 sub-keys, where each of these is always a non-empty array of strings
How I can search over all documents looking inside each of these KEY’s?
For example:
/* MONGO document
{
"_id": {
"$oid": "65fc6b08a0ffe6dd598b114f"
},
"userId": {
"KEY1" : ["1", "2", "3"],
"KEY2" : ["A", "Z"]
...
}
},
{
"_id": {
"$oid": "22fc6b11a0ff111d598b114f"
},
"userId": {
"KEY1" : ["4", "5", "6"],
"KEY2" : ["Z", "X"]
...
},
}
*/
const array = ["2", "X"];
const users = await db.collection("users").find({ "userId": { "$in": array } }).toArray();
console.log(users)
const array = ["2", "X"];
<- I’m trying to specify an array of strings and find all documents
that contains any of these strings in any of the sub-keys arrays of the userId
object
In this case, it would match both documents, because 2
exists on the first document userId.KEY1
and X
exists on the second document userId.KEY2
const array = ["X"];
This would match just the second document
My attempt is not finding any match, how i could achieve this?
3
Answers
To archive your goal, you need to use the MongoDB aggregation framework with
$or
operator and$eleMatch
to search within array of objects.This query will match documents where any of the userId sub-keys contain at least one element that is present in the array
You can use a simple
$or
in yourfind()
query like so:See HERE for a working example.
If you have a long list of
KEYn
keys for exampleKEY1
,KEY2
…KEY99
then you can construct your query object$or
array using a simple for loop like so:You can use
$setIntersection
of the inputarray
with the$setUnion
of the values of KEY’s. Note however that this requires mongo to construct the Union before doing the intersection check which may not be very optimal and won’t use any indexes.Mongo Plaground
And if you have many KEY’s, it fits well with jQueeny’s answer of constructing a string of $KEY’s to use in the
setUnion
part.If you did have an arbitrary number of KEYs – and not always the exact same 4 – you can also use
$objectToArray
as suggested in the comments:Mongo Playground
Also won’t use any index so I’d recommend jQueeny’s answer over this for your scenario.