col*_*ore 7 regex mongodb mongodb-query aggregation-framework
我想在mongodb中使用正则表达式在数组内部进行查询,这些集合包含如下文档:
{
"_id" : ObjectId("53340d07d6429d27e1284c77"),
"company" : "New Company",
"worktypes" : [
{
"name" : "Pompas",
"works" : [
{
"name" : "name 2",
"code" : "A00011",
"price" : "22,22"
},
{
"name" : "name 3",
"code" : "A00011",
"price" : "22,22"
},
{
"name" : "name 4",
"code" : "A00011",
"price" : "22,22"
},
{
"code" : "asdasd",
"name" : "asdads",
"price" : "22"
},
{
"code" : "yy",
"name" : "yy",
"price" : "11"
}
]
},
{
"name" : "name 4",
"works" : [
{
"code" : "A112",
"name" : "Nombre",
"price" : "11,2"
}
]
},
{
"name" : "ee",
works":[
{
"code" : "aa",
"name" : "aa",
"price" : "11"
},
{
"code" : "A00112",
"name" : "Nombre",
"price" : "12,22"
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
}
然后我需要按公司名称查找文档,其中的任何工作都与代码或名称工作中的正则表达式相匹配.我有这个:
var companyquery = { "company": "New Company"};
var regQuery = new RegExp('^A0011.*$', 'i');
db.categories.find({$and: [companyquery,
{$or: [
{"worktypes.works.$.name": regQuery},
{"worktypes.works.$.code": regQuery}
]}]})
Run Code Online (Sandbox Code Playgroud)
但是不要返回任何结果..我认为错误是尝试用de dot和$搜索数组内部..任何想法?
编辑:
有了这个:
db.categories.find({$and: [{"company":"New Company"},
{$or: [
{"worktypes.works.name": {"$regex": "^A00011$|^a00011$"}},
{"worktypes.works.code": {"$regex": "^A00011$|^a00011$"}}
]}]})
Run Code Online (Sandbox Code Playgroud)
这是结果:
{
"_id" : ObjectId("53340d07d6429d27e1284c77"),
"company" : "New Company",
"worktypes" : [
{
"name" : "Pompas",
"works" : [
{
"name" : "name 2",
"code" : "A00011",
"price" : "22,22"
},
{
"code" : "aa",
"name" : "aa",
"price" : "11"
},
{
"code" : "A00112",
"name" : "Nombre",
"price" : "12,22"
},
{
"code" : "asdasd",
"name" : "asdads",
"price" : "22"
},
{
"code" : "yy",
"name" : "yy",
"price" : "11"
}
]
},
{
"name" : "name 4",
"works" : [
{
"code" : "A112",
"name" : "Nombre",
"price" : "11,2"
}
]
},
{
"name" : "Bombillos"
},
{
"name" : "Pompas"
},
{
"name" : "Bombillos 2"
},
{
"name" : "Other type"
},
{
"name" : "Other new type"
}
]
}
Run Code Online (Sandbox Code Playgroud)
正则表达式不会将结果确定为好..
您正在使用JavaScript本机RegExp对象作为正则表达式,但是对于mongo来说处理它需要作为查询文档的一部分发送的正则表达式,这不是一回事.
此正则表达式将与您想要的值不匹配.它可能实际上是^A0111$完全匹配,但是您的大小写不敏感匹配会导致导致更大扫描可能索引的问题.所以有一种更好的方式来编写它.有关不区分大小写的匹配问题,请参阅文档链接.
$regex改为使用运算符:
db.categories.find({
"$and": [
{"company":"New Company"},
{ "$or": [
{ "worktypes.works.name": { "$regex": "^A00011$|^a00011$" }},
{ "worktypes.works.code": { "$regex": "^A00011$|^a00011$" }}
]}
]
})
Run Code Online (Sandbox Code Playgroud)
此外,位置$占位符对查询无效,它们仅用于投影或更新或查询找到的第一个匹配元素.
但是你的实际问题似乎是你试图只获得一个"匹配"条件的数组元素.你不能这样做,为此.find()你需要使用.aggregate():
db.categories.aggregate([
// Always makes sense to match the actual documents
{ "$match": {
"$and": [
{"company":"New Company"},
{ "$or": [
{ "worktypes.works.name": { "$regex": "^A00011$|^a00011$" }},
{ "worktypes.works.code": { "$regex": "^A00011$|^a00011$" }}
]}
]
}},
// Unwind the worktypes array
{ "$unwind": "$worktypes" },
// Unwind the works array
{ "$unwind": "$worktypes.works" },
// Then use match to filter only the matching entries
{ "$match": {
"$or": [
{ "worktypes.works.name": { "$regex": "^A00011$|^a00011$" } },
{ "worktypes.works.code": { "$regex": "^A00011$|^a00011$" } }
]
}},
/* Stop */
// If you "really" need the arrays back then include all the following
// Otherwise the steps up to here actually got you your results
// First put the "works" array back together
{ "$group": {
"_id": {
"_id": "$_id",
"company": "$company",
"workname": "$worktypes.name"
},
"works": { "$push": "$worktypes.works" }
}},
// Then put the "worktypes" array back
{ "$group": {
"_id": "$_id._id",
"company": { "$first": "$_id.company" },
"worktypes": {
"$push": {
"name": "$_id.workname",
"works": "$works"
}
}
}}
])
Run Code Online (Sandbox Code Playgroud)
那么.aggregate()所有这些阶段的作用是将数组元素分解为普通文档形式,以便可以使用$match运算符对它们进行过滤.这样,只返回"匹配"的元素.
"找到"正确做的是匹配符合条件的"文档".由于文档包含匹配的元素,因此返回它们.这两个原则是截然不同的事情.
当你的意思是"过滤"使用聚合.
| 归档时间: |
|
| 查看次数: |
7124 次 |
| 最近记录: |