2016-09-07 78 views
2

我正在使用mongo和nodejs。Mongo +檢查現有的多個字段

我有數組列表:

var checkFields = ["field1","field2","field3"]; 

我試圖讓具有數組列表字段的記錄數和用戶字段等於管理。

樣本數據:

[ 
    { 
     "checkFields": { 
      "field1": "00124b3a5c31", 
      "user": "admin" 
     } 
    }, 
    { 
     "checkFields": { 
      "field2": "00124b3a5c31", 
      "user": "admin" 
     } 
    }, 
    { 
     "checkFields": { 
      "field1": "00124b3a5c31", 
      "user": "regular" 
     } 
    } 
] 

查詢:

db.collection_name.find(
    {"checkFields.user" : "admin"} 
    { "checkFields.field1": { $exists: true} } 
) 

預期結果:

結果是得到在陣列list(checkFields)領域匹配的計數的行。

+1

請分享您的模式 –

+0

{「_id」:ObjectId(「5796fba32dc0d21e774fa074」),「checkFields」:{「id」:「00124b3a5c31」,「user」:「admin」}} – RSKMR

+0

有任何想法做到這一點? – RSKMR

回答

1

構建一個$or陣列現場檢查存在的列表是正確的做法,但假設你在當前的node.js建立可以簡化創建查詢到:

var checkFieldsLists = checkFields.map(field => ({ 
    ['checkFields.' + field]: {$exists: true} 
})); 
var query = { 
    $or: checkFieldsLists, 
    'checkFields.user': 'admin' 
} 

這對於消除多餘$or「用戶管理」檢查,它可以讓您同時刪除外$and,使生成的查詢是:

{ '$or': 
    [ { 'checkFields.field1': { '$exists': true } }, 
    { 'checkFields.field2': { '$exists': true } }, 
    { 'checkFields.field3': { '$exists': true } } ], 
    'checkFields.user': 'admin' } 
+0

感謝您的留言。條件應該是數組列表中的字段,用戶是admin。 – RSKMR

+0

@RSKMR正確,這就是查詢所要做的。查詢的頂層條款隱式與邏輯與。 – JohnnyHK

+0

非常感謝...;。 – RSKMR

0

以下是使用彙總查詢的解決方案。

var Db = require('mongodb').Db, Server = require('mongodb').Server, assert = require('assert'); 

var db = new Db('localhost', new Server('localhost', 27017)); 

var checkFields = ["field1", "field2", "field3"]; 

var checkFieldsLists = []; 
for (var i = 0; i < checkFields.length; i++) { 
    var jsObj = {}; 
    jsObj['checkFields.' + checkFields[i]] = {}; 
    jsObj['checkFields.' + checkFields[i]].$exists = true; 
    checkFieldsLists.push(jsObj); 
} 

var query = { 
    "$and" : [{ 
     "$or" : checkFieldsLists 
    }, { 
     "$or" : [{ 
      "checkFields.user" : "admin" 
     }] 
    }] 
}; 

var matchQuery = { 
    "$match" : { 
     "checkFields.user" : "admin", 
     "$or" : checkFieldsLists 

    } 
}; 

var groupQuery = { 
    $group : { 
     _id : null, 
     count : { 
      $sum : 1 
     } 
    } 
}; 

var aggregateCheckFields = function(db, callback) { 
    console.log("Match query is ====>" + JSON.stringify(matchQuery)); 
    console.log("Group query is ====>" + JSON.stringify(matchQuery)); 
    db.collection('checkfields').aggregate([ matchQuery, groupQuery ]).toArray(
      function(err, result) { 
       assert.equal(err, null); 
       console.log("Result is ===>" + JSON.stringify(result)); 
       if (result.length > 0) { 
        console.log("Count is ===>" + result[0].count); 
       }    
       callback(result); 
      }); 
}; 

db.open(function(err, db) { 

    aggregateCheckFields(db, function() { 
     db.close(); 
    }); 

}); 

輸出: -

Result is ===>[{"_id":null,"count":3}] 
Count is ===>3 
+0

嗨,感謝您的留言。在一個查詢中可能獲得總場1,場2,場3計數(2 + 1 ++ 0)= 3? – RSKMR

+0

字段名稱是否爲靜態I.e.你會在以後增加更多的字段名稱到數組嗎?如果它們是固定的,我會再看一次。 – notionquest

+0

它不是一個靜態的。數組列表將根據條件進行更改。 – RSKMR

0

我嘗試下面的代碼。它的工作,但不知道它的良好解決方案和性能。請任何人有更好的答案意味着請張貼。

var checkFields = ["field1", "field2", "field3"]; 

var checkFieldsLists = []; 
for (i = 0; i < checkFields.length; i++) { 
    var jsObj = {}; 
    jsObj['checkFields.' + checkFields[i]] = {}; 
    jsObj['checkFields.' + checkFields[i]].$exists = true; 
    checkFieldsLists.push(jsObj); 
} 

var query = { 
    "$and" : [{ 
     "$or" : checkFieldsLists 
    }, { 
     "$or" : [{ 
      "checkFields.user" : "admin" 
     }] 
    }] 
}; 

console.log(JSON.stringify(query)); 
//console log will return 
/* 
    {"$and":[{ 
     "$or" : [{ 
      "checkFields.field1" : { 
       "$exists" : true 
      } 
     }, { 
      "checkFields.field2" : { 
       "$exists" : true 
      } 
     }, { 
      "checkFields.field3" : { 
       "$exists" : true 
      } 
     }] 
    }, { 
     "$or" : [{ 
      "checkFields.user" : "admin" 
     }] 
    }] 
} 
*/ 
collection.find(query);