mongoDB:聚合 - 是否有一个等效的本地node.js驱动程序的$ lookup连接?

时间:2016-02-05 20:30:35

标签: node.js mongodb

mongodb:2.1.3

在阅读了mongoDB 3.2中的一些aggregation enhancements后,我很高兴看到" $ look"管道阶段做左外连接。

不幸的是,似乎节点驱动程序没有此操作符。(我在native driver docs for node中看不到它,当我尝试使用它时,我收到错误:

更新:这是我尝试过的代码

var cursor = db.collection('messagethreads').aggregate([
        {"$match": {
            _id: new ObjectID(threadID)}
        }, 
        {"$lookup": {
            from: "messages", 
            localField: "_id",
            foreignField: "threadID",
            as: "messagesList"}
        }
    ]);

    cursor.toArray(function(err,messages){
        if(err) {
            res.status(500).json(error);
        }
        else if(convo === null){
            res.status(400).end();
        }
        else{
            res.status(200).json(messages);
        }
    });
});

示例 - ThreadMessage文档

{ 
    "_id" : ObjectId("56b4f52c0e6368c00630aee6"), 
    name: "Messages 1"
}

示例 - 消息文档

{
     "_id" : ObjectId("56b4f52c0e6368c00630af08"), 
     "author" : "Nick", 
     "text" : "Hello", 
     "threadID" : ObjectId("56b4f52c0e6368c00630aee6")
},
...

预期结果

{
    "_id" : ObjectId("56b4f52c0e6368c00630aee6"), 
    name: "Messages 1",
    messageList:[
        {
         "_id" : ObjectId("56b4f52c0e6368c00630af08"), 
         "author" : "Nick", 
         "text" : "Hello", 
         "threadID" : ObjectId("56b4f52c0e6368c00630aee6")
        },
        ...
    ]
}

" MongoError:exception:无法识别的管道阶段名称:' $ lookup' "

您可以阅读有关联接here的案例的更多信息!

问题:是否有预期的方法来执行与node.js本机驱动程序的等效操作?

1 个答案:

答案 0 :(得分:3)

" MongoError"例外是驱动程序如何报告来自"服务器"的任何错误消息,因此这样的错误表明连接的服务器不是支持$lookup的版本,为3.2或更高版本:

  

$查找

     

版本3.2中的新内容。

     

对同一数据库中的未整数集合执行左外连接,以过滤“已连接”集合中的文档进行处理。 $ lookup阶段在输入文档中的字段与“已连接”集合的文档中的字段之间进行相等匹配。

您始终可以通过serverStatus数据库命令获取要连接的服务器版本。同样在完全可重复的列表中:

var async = require('async'),
    mongodb = require('mongodb'),
    MongoClient = mongodb.MongoClient,
    ObjectId = mongodb.ObjectId;

MongoClient.connect("mongodb://localhost/test",function(err,db) {

  async.series(
    [
      function(callback) {
        db.command({ "serverStatus": 1 }, function(err,status) {
          console.log(status.version);
          callback(err);
        });
      },
      function(callback) {
        async.each(['threadmessage','message'],function(colname,callback) {
          db.collection(colname).remove({},callback);
        },callback);
      },

      function(callback) {
        db.collection('threadmessage').insert(
          {
            "_id" : ObjectId("56b4f52c0e6368c00630aee6"),
            "name": "Messages 1"
          },
          callback
        );
      },

      function(callback) {
        db.collection('message').insert(
          {
            "_id" : ObjectId("56b4f52c0e6368c00630af08"),
            "author" : "Nick",
            "text" : "Hello",
            "threadID" : ObjectId("56b4f52c0e6368c00630aee6")
          },
          callback
        );
      },

      function(callback) {

        var cursor = db.collection('threadmessage').aggregate([
          { "$lookup": {
            "from": "message",
            "localField": "_id",
            "foreignField": "threadID",
            "as": "messagesList"
          }}
        ]);

        cursor.toArray(function(err,result) {
          console.log(JSON.stringify(result,undefined,2));
          callback(err);
        });
      }
    ],
    function(err) {
      if (err) throw err;
      db.close();
    }
  );

});

与固定驱动程序版本的 package.json 一样,只是为了显示没有驱动程序版本问题:

{
  "name": "lookup",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "async": "^1.5.2",
    "mongodb": "2.1.3"
  }
}

使用受支持的服务器版本提供预期输出:

3.2.0
[
  {
    "_id": "56b4f52c0e6368c00630aee6",
    "name": "Messages 1",
    "messagesList": [
      {
        "_id": "56b4f52c0e6368c00630af08",
        "author": "Nick",
        "text": "Hello",
        "threadID": "56b4f52c0e6368c00630aee6"
      }
    ]
  }
]

因此,如果该列表未在您要连接的数据库上返回3.2.x,则此处不支持$lookup管道操作,您必须采用其他方式,例如拉入"相关"信息"客户端"代替。