我可以在node-mongodb-native驱动程序中执行原始MongoDB查询吗?

时间:2017-01-10 08:53:15

标签: node.js mongodb

仅供参考 - 我知道如何使用MongoDB驱动程序并知道这不是在Web应用程序中使用它的方式,但这不适用于Web应用程序。我的目标是在NodeJS中模拟MongoDB shell

我正在编写DB GUI并希望执行原始的MongoDB查询,例如db.tableName.find({ col: 'value' })。我可以使用native MongoDB driver来实现这一目标吗?我使用的是v2.2,这是最新的版本。

如果没有,我如何在NodeJS中实现这一目标?

1 个答案:

答案 0 :(得分:5)

注意:问题已更改 - 请参阅以下更新。

原始答案:

而不是:

db.tableName.find({ col: 'value' })

您将其用作:

db.collection('tableName').find({ col: 'value' }, (err, data) => {
    if (err) {
        // handle error
    } else {
        // you have data here
    }
});

请参阅:http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#find

更新

在您更改了问题并发布了一些评论后,您会更清楚自己想做什么。

要实现在Node中模拟Mongo shell的目标,您需要解析用户键入的命令并执行相应的命令,同时牢记:

  1. Mongo shell使用的SpiderMonkey与V8和libuv的Node之间的区别
  2. BSON和JSON之间的区别
  3. Mongo shell同步工作且Node驱动程序异步工作的事实
  4. 最后一部分可能是你最难的部分。请记住,在Mongo shell中,这是完全合法的:

    db.test.find()[0].x;
    

    在Node中,.find()方法不会返回值,但它会接受回调或返回promise。这将是棘手的。 db.test.find()[0].x;案例可能相对容易处理承诺(如果您理解承诺的话),但这将更难:

    db.test.find({x: db.test.find()[0].x});
    

    并记住你需要处理任意嵌套的级别。

    Mongo协议

    在阅读了一些评论后,我认为值得注意的是,您实际发送给Mongo服务器的内容与您在Mongo shell中编写的JavaScript无关。 Mongo shell使用SpiderMonkey和许多预定义的函数和对象。

    但您实际上并未向Mongo服务器发送JavaScript,因此您无法发送db.collection.find()之类的内容。而是发送二进制OP_QUERY结构,其中集合名称编码为cstring,编码为BSON的查询加上一堆二进制标志。参见:

    BSON本身是一种二进制格式,其中许多低级值定义为字节:

    最重要的是,您不会向Mongo服务器发送类似于您在Mongo shell中输入的内容。 Mongo shell使用SpiderMonkey解析器解析您键入的内容,并将二进制请求发送到实际的Mongo服务器。 Mongo shell使用JavaScript,但您不能使用JavaScript与Mongo服务器通信。

    实施例

    即使是JSON查询对象也不会以JSON的形式发送给Mongo。例如,当您搜索hello属性等于" world"您可以在JavaScript中使用{hello: 'world'}或在JSON中使用{"hello": "world"}但是这是Mongo shell或任何其他Mongo客户端发送到Mongo服务器的内容:

    \x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00   
    

    为什么它如此不同

    要理解为什么Node中使用的语法与Mongo shell有很大不同,请参阅以下答案: