Suppose I have multiple fields in a document whose key value I don't know(only the user who has added the keys know that)
Now suppose user wants to finds a document specifying the key value, but he forgot what his key value was EXACTLY
So say I have this document:
name: "John Doe"
class: 5
MisChief: "Bullying"
where the MisChief key was custom created.
Suppose user wants to search for 'mischief: bullying'
I can use $regex
operator to search for the value, but how can I specify the key as a regex expression ?
Another way to do this is to return all documents, and doing a case insensitive search for the keys from all those documents which is very inefficient.
So with unknown/dynamic/random key names, one way to do it using aggregation operator $objectToArray
:
db.collection.aggregate([
/** Add a new array field to all docs which contains each field as {k:...,v:...} */
{
$addFields: { data: { $objectToArray: "$$ROOT" } }
},
/** Match docs that has an object in `data` array which matches with input */
{
$match: { "data": { "$elemMatch": { "k": "MisChief", "v": "Bullying" } } } // can be a regex /MisChief/i
},
/** Remove added array field from output */
{
$project: { "data": 0 }
}
])
Test: mongoplayground
Ref:aggregation
From your statement:
but he forgot what his key value was EXACTLY
If he vaguely remembers Key name/value but doesn't remember it completely - You can do it using regex as you wanted ! But if he forgets it entirely then you can't do much just get all docs where data.v: 'Bullying'
& use $match
stage to filter further on name
of user.
db.collection.aggregate([
{
$addFields: { data: { $objectToArray: "$$ROOT" } }
},
{
$match: { "data": { "$elemMatch": { "v": "Bullying" } } }
},
{
$project: { "data": 0 }
}
])
Test: mongoplayground
Note:
For one single element { "v": "Bullying" }
we don't need to use $elemMatch
but to keep syntax consistent we're using it, otherwise you can just use data.v: 'Bullying'
in $match
stage.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.