2017-02-20 58 views
2

我想在MongDB中编写一个查询来选择用户部分完成其配置文件的所有行。MongoDB查询哪里不是全部

凡F1或F2或F3为空或“”但不是在三个字段为空或“”

我的意思是其中一个或两个的三个字段为空,但不是三个字段

我已经试过这不返回预期的记录: 修订

var query = { 
     $or:[ 
      {"profile.public.f1": {$in: [null, false, '']}}, 
      {"profile.public.f2": {$in: [null, false, '']}}, 
      {"profile.public.f3": {$in: [null, false, '']}} 
     ] 
}; 

此查询中使用的NodeJS像这样:

function GetDocument(model, query, projection, extension, callback) { 
    var query = db[model].find(query, projection, extension.options); 
    if (extension.populate) { 
     query.populate(extension.populate); 
    } 
    if (extension.sort) { 
     query.sort(extension.sort); 
    } 
    query.exec(function (err, docs) { 
    if (extension.count) { 
     query.count(function (err, docs) { 
      callback(err, docs); 
     }); 
    } else { 
     callback(err, docs); 
    } 
    }); 
} 

再后来:

db.GetDocument('users', query, {}, {}, function (err, docdata) { 
     console.log(docdata)   
}); 

回答

0

使用$其中:

> db.createCollection("t"); 
{ "ok" : 1 } 
> db.t.insert({f1:'a',f2:'',f3:''}); 
WriteResult({ "nInserted" : 1 }) 
> db.t.insert({f1:'',f2:'',f3:null}); 
WriteResult({ "nInserted" : 1 }) 
> db.t.insert({f1:'',f2:'',f3:''}); 
WriteResult({ "nInserted" : 1 }) 
> db.t.insert({f1:'',f2:''}); 
WriteResult({ "nInserted" : 1 }) 
> db.t.find(); 
{ "_id" : ObjectId("58aab60118633becf0ac4f80"), "f1" : "a", "f2" : "", "f3" : "" } 
{ "_id" : ObjectId("58aab60718633becf0ac4f81"), "f1" : "", "f2" : "", "f3" : null } 
{ "_id" : ObjectId("58aab61018633becf0ac4f82"), "f1" : "", "f2" : "", "f3" : "" } 
{ "_id" : ObjectId("58aab65618633becf0ac4f83"), "f1" : "", "f2" : "" } 
> var q = {$where: function() {return ((this.f1.length||'') + (this.f2.length||'') +(this.f3 || '').length) >0;}}; 
> db.t.find(q); 
{ "_id" : ObjectId("58aab60118633becf0ac4f80"), "f1" : "a", "f2" : "", "f3" : "" } 

查询故障:

{ 
    $where: function(){ 
    return((this.f1.length||'')+(this.f2.length||'')+(this.f3||'').length)>0; 
    } 
}; 

其中应返回true =>字符串的总和(字段值)必须大于零。这样如果fieldN ='',那么它的长度等于零,如果所有三个都等于零,它们的总和将为零(0 + 0 + 0)= 0,但是如果至少有一个值为<>那么它将返回true,这样就实现了where子句。

现在的问题是,null.length不会工作,所以我们要么将其包装在String(null)中,要么给出任何合适的值,如果它失败了,所以我们来语义错误,但更短,工作this.f1.length||''如果第一第二部作品失败。运营商OR拿起第一个工作日值...

,如果你想在它的NodeJS,不蒙戈贝壳,这里的例子:

[email protected]:~$ nodejs 
> var MongoClient = require('mongodb').MongoClient, 
... co = require('co'), 
... assert = require('assert'); 
undefined 
> 
> co(function*() { 
... var db = yield MongoClient.connect('mongodb://localhost:27017/test'); 
... var col = db.collection('t'); 
... var q = {$where: function() {return ((this.f1.length||'') + (this.f2.length||'') +(this.f3 || '').length) >0;}}; 
... //var cursor = col.find({f1.length:{$gt:0}}); 
... var cursor = col.find({f1:"a"}); 
... col.find().toArray(function(err, items) {}); 
... var stream = col.find(q).stream(); 
... stream.on("data", function(item) {}); 
... stream.on("end", function() {}); 
... 
... while(yield cursor.hasNext()) { 
...  var doc = yield cursor.next(); 
...  console.dir(doc); 
... } 
... 
... db.close(); 
... }).catch(function(err) { 
... console.log(err.stack); 
... }); 
Promise { <pending> } 
> 
> { _id: 
    ObjectID { 
    _bsontype: 'ObjectID', 
    id: 
     Buffer { 
     '0': 88, 
     '1': 172, 
     '2': 1, 
     '3': 143, 
     '4': 157, 
     '5': 175, 
     '6': 27, 
     '7': 230, 
     '8': 160, 
     '9': 208, 
     '10': 69, 
     '11': 88 } }, 
    f1: 'a', 
    f2: '', 
    f3: '' } 

(To exit, press ^C again or type .exit) 
> 
+0

请你能帮助详细解释这一点:它分解:'变种q = {$其中:function(){return((this.f1.length ||'')+(this.f2.length ||'')+(this.f3 ||'').length)> 0 ;}};' – Digitlimit

+0

已更新的答案。对不起,错别字 - 家里的笔记本电脑很不舒服 –

+0

Vao Tsun感谢你的所有努力。这可以在nodejs中工作吗? – Digitlimit