我想从集合中找到部分匹配某个字符串的所有键名.
我得到的最接近的是检查某个密钥是否存在,但这是一个完全匹配:
db.collection.find({ "fkClientID": { $exists:1 }})
我想得到所有以fk开头的键.
解决方法:
如果您有最新的MongoDB 3.4.4,那么您可以在聚合语句中使用$objectToArray,其中$redact
作为最快速的方式,可以使用本机运算符.不是扫描集合是“快”.但是你得到的速度最快:
db[collname].aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": { "$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "doc",
"cond": {
"$eq": [ { "$substr": [ "$$doc.k", 0, 2 ] }, "fk" ]
}
}}},
0
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
当前未记录的$objectToArray将“对象”转换为数组中的“键”和“值”形式.所以这:
{ "a": 1, "b": 2 }
变成这样:
[{ "k": "a", "v": 1 }, { "k": "b", "v": 2 }]
与$$ROOT一起使用,这是一个引用当前文档“对象”的特殊变量,我们转换为数组,因此可以检查“k”的值.
然后,只需应用$filter并使用$substr来获取“key”字符串的前面字符.
为了记录,这将是MongoDB 3.4.4获得匹配键的唯一列表的最佳方式:
db[collname].aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": { "$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "doc",
"cond": {
"$eq": [ { "$substr": [ "$$doc.k", 0, 2 ] }, "fk" ]
}
}}},
0
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"j": {
"$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "doc",
"cond": {
"$eq": [ { "$substr": [ "$$doc.k", 0, 2 ] }, "fk" ]
}
}
}
}},
{ "$unwind": "$j" },
{ "$group": { "_id": "$j.k" }}
])
这是安全规定,它考虑到密钥可能不存在于所有文档中,并且文档中可能存在多个密钥.
如果你完全确定你“总是”拥有文档中的密钥并且只有一个密钥,那么你可以缩短到只有$group:
db[colname].aggregate([
{ "$group": {
"_id": {
"$arrayElemAt": [
{ "$map": {
"input": { "$filter": {
"input": { "$objectToArray": "$$ROOT" },
"as": "doc",
"cond": {
"$eq": [ { "$substr": [ "$$doc.k", 0, 2 ] }, "fk" ]
}
}},
"as": "el",
"in": "$$el.k"
}},
0
]
}
}}
])
早期版本中最有效的方法是使用允许JavaScript表达式进行评估的$where
语法.并不是说评估JavaScript的任何东西都是你能做的“最有效”的事情,但分析“密钥”而不是“数据”并不是任何数据存储的最佳选择:
db[collname].find(function() { return Object.keys(this).some( k => /^fk/.test(k) ) })
内联函数只有shell简写,这也可以写成:
db[collname].find({ "$where": "return Object.keys(this).some( k => /^fk/.test(k) )" })
$where
的唯一要求是表达式为您要返回的任何文档返回true值,因此文档将保持不变.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。