我有一个可以在 mongo shell 中运行的查询
db.getCollection('insights').find({$and:[{author:/jim/i}]})
返回 2 条记录。
调用 waterline/sailsjs-mongo 的“or”代码
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 条记录。
我使用 native 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 和 Waterline 版本为“0.12.1”
在 sails-mongodb 中调用 mongodb $and 查询的正确方法是什么?
最佳答案
https://docs.mongodb.com/manual/reference/operator/query/and/#and
$and performs a logical AND operation on an array of two or more expressions (e.g. expression1, expression2, etc.) and selects the documents that satisfy all the expressions in the array. The $and operator uses short-circuit evaluation. If the first expression (e.g. expression1) evaluates to false, MongoDB will not evaluate the remaining expressions.
因此,在您的情况下,使用 AND 运算符甚至没有意义,因为您也可以使用隐式 AND,例如
db.getCollection('insights').find({author:/jim/i})
解决您的实际问题。我无法使用 native mongodb 重现此问题。在外壳中:
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 }
我得到了预期的结果。但是,当我尝试使用嵌套的水线查询和/或我看到与您描述的相同的问题。让我们看一下以下 native 查询:
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 根本不支持 and/or 运算符的嵌套但我找不到任何证据。您可以在他们的 github 页面上提交功能请求。
作为解决方法,您可以使用 native 底层 mongodb 适配器来创建查询。缺点是您的代码将与数据库无关。
关于node.js - 如何使用 sails-mongodb 获取 'and' 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39303895/