node.js - 如何使用 sails-mongodb 获取 'and' 查询

标签 node.js mongodb express sails.js

我有一个可以在 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/

相关文章:

php - MongoDB/PHP 库 : $regex does not work

mongodb - Mongod 错误 : 98 Unable to lock file:/data/db/mongod. 锁定资源暂时不可用。 mongod 实例是否已经在运行?

javascript - Nodejs Plotlyjs 单独工作但不能一起工作

javascript - Object #<MongoClient> 没有方法 'open'

javascript - NodeJS : Events on child processes

node.js - 同步文本编辑

javascript - 如何使用socket.io获取数据表 "status"列中的进度状态

javascript - 尝试使用 Node JS 设置 API 管理 REST API 身份验证

node.js - 如何访问所有模板中的自定义对象表达应用程序?

node.js - MongoDB 不报告关闭连接