我有一个在mongo shell中工作的查询
db.getCollection('insights').find({$and:[{author:/jim/i}]})
返回2条记录。
'或'代码调用waterline / sailsjs-mongo
db('insights').find({
or: [
{or: [ {author: new RegExp( ".*"+"jim"+".*", 'i' )} ] }
]
}).limit(req.params.limit).skip(req.params.offset).exec(function (err, insights) { ... }
按预期返回2条记录。
如果我将'或'更改为'和'
db('insights').find({
or: [
{and: [ {author: new RegExp( ".*"+"jim"+".*", 'i' )} ] }
]
}).limit(req.params.limit).skip(req.params.offset).exec(function (err, insights) { ... }
我得到0条记录,这是不可预期的。它应该返回2条记录。
我使用原生mongodb javascript客户端编写了一些代码。
var MongoClient = require('mongodb').MongoClient,
test = require('assert');
// Connection url
var url = 'mongodb://localhost:27017/infosystem';
// Connect using MongoClient
MongoClient.connect(url, function(err, db) {
// Create a collection we want to drop later
var col = db.collection('insights');
// Show that duplicate records got dropped
col.find({$and:[{author: new RegExp('.*Jim.*','i')}]}).toArray(function(err, items) {
test.equal(null, err);
test.equal(2, items.length);
db.close();
});
});
当运行时不会抛出任何断言。
node test_insights.js
mongodb是版本3.2.9,sails-mongodb和水线是版本“0.12.1”
在sails-mongodb中调用mongodb $和查询的正确方法是什么?
答案 0 :(得分:1)
https://docs.mongodb.com/manual/reference/operator/query/and/#and
$并对两个或更多的数组执行逻辑AND运算 表达式(例如expression1,expression2等)并选择 满足数组中所有表达式的文档。 $和 操作员使用短路评估。如果是第一个表达式(例如 expression1)计算结果为false,MongoDB不会评估 剩下的表达。
所以在你的情况下,使用AND运算符甚至没有意义,因为你也可以使用隐式AND,比如
db.getCollection('insights').find({author:/jim/i})
来解决你的实际问题。我无法使用本机mongodb重现此问题。在shell中:
db.collection.insert({name:'Foo', age:28})
db.collection.insert({name:'Bar', age:32})
db.collection.find()
{ "_id" : ObjectId("57ca84c374f2776cc983ad9e"), "name" : "Foo", "age" : 28 }
{ "_id" : ObjectId("57ca84cd74f2776cc983ad9f"), "name" : "Bar", "age" : 32 }
db.collection.find({$and:[{name:new RegExp('.*Fo.*','i')}]})
{ "_id" : ObjectId("57ca84c374f2776cc983ad9e"), "name" : "Foo", "age" : 28 }
> db.collection.find({$or:[{$or:[{name:new RegExp('.*Fo.*','i')}]}]})
{ "_id" : ObjectId("57ca84c374f2776cc983ad9e"), "name" : "Foo", "age" : 28 }
> db.collection.find({$or:[{$and:[{name:new RegExp('.*Fo.*','i')}]}]})
{ "_id" : ObjectId("57ca84c374f2776cc983ad9e"), "name" : "Foo", "age" : 28 }
我得到了预期的结果。但是,当我尝试使用嵌套的水线查询和/或我看到你描述的相同问题。让我们看看以下原生查询:
db.collection.find({$or:[{$and:[{name:'Foo'}, {age:28}]}, {name:'Bar'}]})
正确返回:
{ "_id" : ObjectId("57ca84c374f2776cc983ad9e"), "name" : "Foo", "age" : 28 }
{ "_id" : ObjectId("57ca84cd74f2776cc983ad9f"), "name" : "Bar", "age" : 32 }
现在让我们在水线中创建相同的查询:
Test.find({
or: [
{and: [{name:'Foo'},{age:28}]},
{name: 'Bar'}
]
})
这会返回[]
。可以在此处找到负责和/或查询的相关代码:https://github.com/balderdashy/sails-mongo/blob/master/lib/query/index.js#L132
我确信sails-mongo根本不支持和/或运算符的嵌套,但我无法找到任何证据。您可以在他们的github页面上提交功能请求。
作为一种解决方法,您可以使用本机底层mongodb适配器来创建查询。作为缺点,您的代码不会与数据库无关。