我正在尝试使用mongodb 2.6.1版中的以下查询来过滤mongo数据但是收到错误。
MongoDB版本2.4.6(工作):
> db.BC_1839.find({data: {$elemMatch:{$where : "this.First_name.toLowerCase().indexOf('kim') ==0"}}});
输出:
{
"_id" : ObjectId("53719a9d5b9e5c8c110001b9"),
"data" : [
{
"First_name" : "Kimberely",
"Last_name" : "Weyman",
"Company_name" : "Scientific Agrcltl Svc Inc",
"Address" : "7721 Harrison St",
"City" : "Kingsway West",
"State" : "NS",
"Post" : "2208",
"Phone1" : "02-7091-8948",
"Phone2" : "0441-151-810",
"Email" : "kweyman@weyman.com.au",
"Web" : "http://www.scientificagrcltlsvcinc.com.au",
"active" : "true"
}
],
"history" : [
{
"timestamp" : "2014-05-13 06:07:55",
"event": "creation",
"createdby" : "Srikesh Infotech",
"creation_data" : [
{
"crm_base_contact_id" : "1839",
"crm_imported_files_id" : "1464"
}
]
},
{
"timestamp" : "2014-05-13 06:09:05",
"event" : "Task",
"createdby" : "Srikesh Infotech",
"Task_data" : [
{
"Campaign ID" : "193",
"Campagin Name" : "Test Campa1"
}
]
}
],
"ref" : [
{ "crm_base_contact_id" : "1839", "crm_imported_files_id" : "1464" }
]
}
MongoDB版本2.6.1(不工作):
> db.BC_1839.find({data: {$elemMatch:{$where : "this.First_name.toLowerCase().indexOf('kim') ==0"}}});
输出:
error: {
"$err" : "Can't canonicalize query: BadValue $elemMatch cannot contain $
where expression",
"code" : 17287
}
相同的查询在mongodb版本2.4.6中执行但在mongodb版本2.6.1中不执行为什么???
答案 0 :(得分:3)
它根本不应该在早期版本中工作,因为至少你修改了this
的范围,现在引用"数据"作为顶级元素。简而言之,不再允许这样做,除非你绝对必须,否则你真的不应该使用JavaScript方法。即便如此,在大多数情况下仍有更好的方法。
但实际上这是JavaScript匹配的必要使用,因为当存在其他运算符时,它不需要这样做。
您应该使用$regex
表单:
db.docs.find({ "data.First_name": /^kim/i })
或在字段中的任何位置,删除插入符^
:
db.docs.find({ "data.First_name": /kim/i })
这与JavaScript执行效率低得多,但没有通过该解释器引擎处理的开销。当然,它无处不在。
还要考虑依赖JavaScript解析的查询实际上是在做什么:
true|false
转换回来
考虑到$regex
(但是不区分大小写不匹配)正在执行相同的操作,但使用" pcre" C库本身没有转换和每个文档的重铸,那么它显然是两者的理智选择。