Mat*_*t P 9 regex lookup mongodb
我有一些文件保存在一个集合(称为urls)中,如下所示:
{
payload:{
url_google.com:{
url:'google.com',
text:'search'
}
}
},
{
payload:{
url_t.co:{
url:'t.co',
text:'url shortener'
}
}
},
{
payload:{
url_facebook.com:{
url:'facebook.com',
text:'social network'
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用mongo CLI,是否可以查找payload匹配的子文档/^url_/?并且,如果可能的话,是否也可以查询匹配的子文档(例如,确保text存在)?
我在想这样的事情:
db.urls.find({"payload":{"$regex":/^url_/}}).count();
Run Code Online (Sandbox Code Playgroud)
但那是0结果.
任何帮助或建议都会很棒.
谢谢,
马特
以这种方式查询文档密钥是不可能的.您可以使用搜索完全匹配$exists,但找不到与模式匹配的键名.
我假设(可能不正确)您正在尝试查找具有URL子文档的文档,并且并非所有文档都具有此文档?为什么不将类型信息推到一个级别,例如:
{
payload: {
type: "url",
url: "Facebook.com",
...
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以查询如下:
db.foo.find({"payload.type": "url", ...})
Run Code Online (Sandbox Code Playgroud)
如果我没有注意到你不应该使用dot(.)是MongoDB中的关键名称,我也会失职.在某些情况下,可以创建这样的文档,但是当您尝试查询嵌入文档时,它会引起很大的混淆(Mongo使用dot作为"路径分隔符").
您可以这样做,但需要使用聚合:聚合是管道,其中每个阶段都应用于每个文档。您有广泛的阶段来执行各种任务。
我为这个特定问题编写了一个聚合管道。如果您不需要计数但需要文档本身,您可能想看看舞台$replaceRoot。
编辑:这仅适用于 Mongo v3.4.4 及以上版本(感谢@hwase0ng 的提示)
db.getCollection('urls').aggregate([
{
// creating a nested array with keys and values
// of the payload subdocument.
// all other fields of the original document
// are removed and only the filed arrayofkeyvalue persists
"$project": {
"arrayofkeyvalue": {
"$objectToArray": "$$ROOT.payload"
}
}
},
{
"$project": {
// extract only the keys of the array
"urlKeys": "$arrayofkeyvalue.k"
}
},
{
// merge all documents
"$group": {
// _id is mandatory and can be set
// in our case to any value
"_id": 1,
// create one big (unfortunately double
// nested) array with the keys
"urls": {
"$push": "$urlKeys"
}
}
},
{
// "explode" the array and create
// one document for each entry
"$unwind": "$urls"
},
{
// "explode" again as the arry
// is nested twice ...
"$unwind": "$urls"
},
{
// now "query" the documents
// with your regex
"$match": {
"urls": {
"$regex": /url_/
}
}
},
{
// finally count the number of
// matched documents
"$count": "count"
}
])
Run Code Online (Sandbox Code Playgroud)