2017-02-20 3 views
2

Я пытаюсь написать запрос в MongDB, чтобы выбрать все строки, в которых пользователи частично завершили свои профили.MongoDB Query, где не все

Где 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; 
    } 
}; 

где должна возвращать истина => сумма строки (значение поля) должно быть более терма, чем ноль. Таким образом, uf 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 = {$ where: function() {return ((this.f1.length || '') + (this.f2.length || '') + (this.f3 || '') .length)> 0 ;}}; ' – Digitlimit

+0

обновленный ответ. извините за опечатки - домашний ноутбук очень неудобен –

+0

Vao Tsun благодарит за все ваши усилия. Может ли это работать в nodejs? – Digitlimit

Смежные вопросы