Regex mongoDB中数组内部的正则表达式
我想使用regex在mongodb中的数组中进行查询,集合中有如下文档:Regex mongoDB中数组内部的正则表达式,regex,mongodb,mongodb-query,aggregation-framework,Regex,Mongodb,Mongodb Query,Aggregation Framework,我想使用regex在mongodb中的数组中进行查询,集合中有如下文档: { "_id" : ObjectId("53340d07d6429d27e1284c77"), "company" : "New Company", "worktypes" : [ { "name" : "Pompas", "works" : [ { "name" : "name 2", "c
{
"_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"
}
]
}
]
}
然后,我需要找到一个文件的公司名称和任何工作,其中有匹配的代码或名称工作正则表达式。
我有这个:
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}
]}]})
但是不要返回任何结果..我认为错误是尝试使用de dot和$在数组内部搜索。。
有什么想法吗
编辑:
为此:
db.categories.find({$and: [{"company":"New Company"},
{$or: [
{"worktypes.works.name": {"$regex": "^A00011$|^a00011$"}},
{"worktypes.works.code": {"$regex": "^A00011$|^a00011$"}}
]}]})
结果是:
{
"_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"
}
]
}
正则表达式不输入结果正常。我认为有一个输入错误: 正则表达式应为:
^A00011.$
三重0而不是双0您正在为正则表达式使用JavaScript本机
RegExp
对象,但是对于mongo来说,要处理正则表达式,它需要作为查询文档的一部分发送,这是不同的
此外,正则表达式将与所需的值不匹配。对于精确匹配,它实际上可能是^A0111$
,但不区分大小写的匹配会导致一个问题,导致对可能的索引进行更大的扫描。所以有一个更好的方法来写。有关不区分大小写匹配的问题,请参见文档链接
请改用运算符:
db.categories.find({
"$and": [
{"company":"New Company"},
{ "$or": [
{ "worktypes.works.name": { "$regex": "^A00011$|^a00011$" }},
{ "worktypes.works.code": { "$regex": "^A00011$|^a00011$" }}
]}
]
})
此外,位置占位符$
对于查询无效,它们仅用于投影、更新或查询找到的第一个匹配元素
但您的实际问题似乎是,您试图只获取与您的条件“匹配”的数组元素。您不能使用.find()
执行此操作,为此,您需要使用:
所有这些阶段的作用是将数组元素分解为正常的文档形式,这样就可以使用$match
操作符对它们进行过滤。这样,只返回“匹配”的元素
“查找”正确的做法是匹配满足条件的“文档”。由于文档包含匹配的元素,因此将返回这些元素。这两个原则是截然不同的
当你想“过滤”时,使用聚合。什么是
regexQuery
?它是一个带有regex值的字符串,我已经从nodejs客户端复制了我的代码,我将编辑我的问题。ThanlsI认为问题之一是位置运算符$
是投影/更新运算符,而不是查询运算符,请尝试更接近于:“worktypes.works.name”
,而不是“worktypes.works.$.name”
相同的结果。无需显示:(等等,你想要什么结果?该文档确实填充了结果,但结果不一样。我尝试了大多数代码和名称,但任何代码和名称都不起作用。@colymore结果中的文档实际上包含与表达式匹配的元素。那么你真的要“筛选”吗数组的结果是否只返回匹配项?这是另一回事。我试图仅获取其worktype.work.code或name与正则表达式匹配的worktypes.works,并放弃worktypes.works,而不是..正则表达式对象将被转换为BSON正则表达式对象,正如文档中所示。BSON正则表达式对象t不能直接转换为$regex运算符。@colymore,这就是我在评论中所说的。实际上,您要求的是“查找”的内容不需要。请参阅其他信息。@colymore,因此我实际上已经花了时间复制了您的数据,并运行了给定的最终聚合表达式。编辑在响应中,整个链按预期工作。因此,您没有理由不接受这一点。我已经指出了您原始方法的几个问题,并且提供了一个正确的解决方案来实际过滤阵列。实际接受您得到的建议会更好:)
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"
}
}
}}
])