[英]MongoDB filter docs on dynamic key and value using regex
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. MisChief 键是自定义创建的。
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 ?我可以使用
$regex
运算符来搜索值,但是如何将键指定为正则表达式?
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
:因此,对于未知/动态/随机键名,一种使用聚合运算符
$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测试: 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.但是,如果他完全忘记了,那么您将无能为力,只需获取
data.v: 'Bullying'
所有文档并使用$match
阶段进一步过滤用户name
。
db.collection.aggregate([
{
$addFields: { data: { $objectToArray: "$$ROOT" } }
},
{
$match: { "data": { "$elemMatch": { "v": "Bullying" } } }
},
{
$project: { "data": 0 }
}
])
Test: mongoplayground测试: 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.对于单个元素
{ "v": "Bullying" }
,我们不需要使用$elemMatch
,但为了保持语法一致,我们正在使用它,否则您可以在$match
阶段使用data.v: 'Bullying'
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.