0

次のクエリで同じコレクションの結果が必要な場合、ネストされたクエリをどのように実行しますか?

var mongo = require('../config/mongo');

var mongoDB = mongo.db;
...

exports.myFunction = function(req, res) {

...
...
// e.g. myArray = ['a','b','c'];

mongoDB.collection('MyCollection', function(err, collection) {
    collection.find({ $or: [{ 'source': {$in: myArray} },{ 'target': {$in: myArray} }]}, { "someVar": 0}).toArray(function(err, firstResults) {

            var allResults = [];
            for (var i = 0; i < firstResults.length; i++) {
                allResults[firstResults[i].source]=1;
                allResults[firstResults[i].target]=1;
            };

            var secondResults = Object.keys(allResults);

            mongoDB.collection('MyCollection', function(err, collection) {
                collection.find({ $or: [{ 'source': {$in: secondResults} },{ 'target': {$in: secondResults} }]}, { "someVar": 0}).toArray(function(err, items) {
                    res.send(items);
                });
            });


    });
});

しかし、同じコレクション 'MyCollection' を 2 回呼び出すのは好きではありません。ソースまたはターゲットに secondResults が含まれるドキュメントを取得しようとしています。

4

1 に答える 1

5

「MyCollection」を開くための 2 番目の呼び出しを取り除く必要があります。'MyCollection' オブジェクトを一度開いた後は、既に 'MyCollection' オブジェクトがあります。つまり、これがあります:

mongoDB.collection('MyCollection', function(err, collection) {
  collection.find({ $or: [{ 'source': {$in: secondResults} },{ 'target': {$in: secondResults} }]}, { "someVar": 0}).toArray(function(err, items) {
    res.send(items);
   });
});

しかし、あなたはすでにここから「MyCollection」のインスタンスを持っています:

mongoDB.collection('MyCollection', function(err, collection) {
  collection.find({ $or: [{ 'source': {$in: myArray} },{ 'target': {$in: myArray} }]}, { "someVar": 0}).toArray(function(err, firstResults) {

したがって、「collection」への 2 番目の呼び出しは最初の呼び出しのスコープ内にあるため、そのインスタンスを再利用できます (再利用する必要があります)。

collection.find({ $or: [{ 'source': {$in: secondResults} },{ 'target': {$in: secondResults} }]}, { "someVar": 0}).toArray(function(err, items) {
  res.send(items);
});

または、 node-mongodb-nativeを使用している場合は、いくつかの例を見て、目的を達成する他の方法を確認できます。

更新 1

このコードは私のために働きます:

var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db){
  if(err) throw err;

  var collection = db.collection('c');
  var secondQuery = {};

  collection.find({a:'b'}).toArray(function(err, firstRes){
    for(var i = 0; i < firstRes.length; i++){
      secondQuery[firstRes[i].a] = firstRes[i].b;
    }

    collection.find(secondQuery).toArray(function(err, secondRes){
      for(var i = 0; i < secondRes.length; i++){
        console.log(secondRes[i]);
      }

      db.close();
    });
  });
});

更新 2

上記のコードはnode-mongodb-native バージョン 1.3.19を使用していることに注意してください。バージョン 1.2 以降、Node.js ドライバーから mongodb を操作する場合は、MongoClient を使用することをお勧めします。

于 2013-11-11T16:49:36.780 に答える