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

Rig*_*eek 2 mongodb node.js

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

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

如果没有,我怎样才能在NodeJS中实现这一目标?

rsp*_*rsp 5

注意:问题已更改 - 请参阅下面的更新.

原始答案:

是.

代替:

db.tableName.find({ col: 'value' })
Run Code Online (Sandbox Code Playgroud)

你用它作为:

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

请参阅: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驱动程序异步工作

最后一部分可能是最困难的部分.请记住,在Mongo shell中,这是完全合法的:

db.test.find()[0].x;
Run Code Online (Sandbox Code Playgroud)

在Node中,该.find()方法不返回值,但它接受回调或返回promise.这将是棘手的.这种db.test.find()[0].x;情况可能相对容易处理承诺(如果你很好地理解承诺),但这将更难:

db.test.find({x: db.test.find()[0].x});
Run Code Online (Sandbox Code Playgroud)

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

Mongo协议

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

但是你实际上并没有将JavaScript发送到Mongo服务器,所以你不能发送类似的东西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" 的文档时,您将{hello: 'world'}在JavaScript或{"hello": "world"}JSON中使用,但这是通过Mongo shell或任何其他Mongo客户端发送到Mongo服务器的内容:

\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00   
Run Code Online (Sandbox Code Playgroud)

为什么它如此不同

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

  • @RiggerTheGeek 您不会将 `db.collection.find()` 发送给 Mongo。您发送诸如`OP_QUERY`结构之类的东西,其集合名称作为cstring,查询作为BSON加上一堆二进制标志 - 请参阅:https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/# wire-op-query 这是二进制协议。您不会发送与您在 Mongo shell 中输入的内容类似的任何内容。Mongo shell 使用 SpiderMonkey 解析器解析您输入的内容,并将二进制请求发送到实际的 Mongo 服务器。这不是文本协议。Mongo shell 使用 JS,但您不与 JS 中的 Mongo 通信。 (2认同)