在Field Projection中忽略batchSize字段名称

Mon*_*sha 3 javascript mongodb node.js

我有一个user_batch集合.它包含以下文件:

[{
  _id: ObjectId("594baf96256597ec035df23c"),
  name: "Batch 1",
  batchSize: 30,
  users:[]
 },
 {
  _id: ObjectId("594baf96256597ec035df234"),
  name: "Batch 2",
  batchSize: 50,
  users:[]
 }]
Run Code Online (Sandbox Code Playgroud)

在查找查询中,我想仅项目名称batchSize.但是当我从nodejs执行查询查询时,我在查询结果中获取整个文档.查询:

db.collection('user_batch').find({}, {name: 1, batchSize: 1}).toArray((err, result) => {
  if(err) 
    console.log(err)
  else
    console.log(result)
})
Run Code Online (Sandbox Code Playgroud)

如果我只是传递{name:1},那么它将投影_id并命名.但是如果我传递batchSize那么它将返回整个文档.

注意:在Mongo Shell中执行此查询时,我没有遇到此问题

Nei*_*unn 8

你是正确的,驱动程序错误地将此解释为batchSize选项并忽略投影语句.

在现代驱动程序版本中执行此操作的正确方法是实际使用.project()"游标方法".这与其他语言驱动程序实现更加一致.

    db.collection('collection').find()
      .project({ name: 1, batchSize: 1})
      .toArray();
Run Code Online (Sandbox Code Playgroud)

作为一个完整的演示:

const mongodb = require('mongodb'),
      MongoClient = mongodb.MongoClient;


(async function() {

  let db;

  try {
    db = await MongoClient.connect('mongodb://localhost/test');

    // New form uses .project() as a cursor method
    let result = await db.collection('collection').find()
      .project({ name: 1, batchSize: 1})
      .toArray();

    console.log(JSON.stringify(result,undefined,2));

    // Legacy form confuses this as being a legacy "cursor option"
    let other = await db.collection('collection')
      .find({},{ name: 1, batchSize: 1 })
      .toArray();

    console.log(JSON.stringify(other,undefined,2));

  } catch(e) {
    console.error(e)
  } finally {
    db.close()
  }

})()
Run Code Online (Sandbox Code Playgroud)

产生输出:

[
  {
    "_id": "594baf96256597ec035df23c",
    "name": "Batch 1",
    "batchSize": 30
  },
  {
    "_id": "594baf96256597ec035df234",
    "name": "Batch 2",
    "batchSize": 50
  }
]
[
  {
    "_id": "594baf96256597ec035df23c",
    "name": "Batch 1",
    "batchSize": 30,
    "users": []
  },
  {
    "_id": "594baf96256597ec035df234",
    "name": "Batch 2",
    "batchSize": 50,
    "users": []
  }
]
Run Code Online (Sandbox Code Playgroud)

第一个输出形式是经过修正的形式,使用 .project()


Wyc*_*yck 6

的语法Find已更改。以下是我需要了解的解决此问题的信息。这是摘自https://github.com/mongodb/node-mongodb-native/blob/master/CHANGES_3.0.0.md#find

寻找

find并且findOne不再支持该fields参数。fields通过使用选项对象Cursor.prototype.project或传递projection选项对象的属性,可以获得与参数相同的结果。此外,find不支持像skiplimit作为位置参数的单独选项。您必须在对象中传递这些参数,options或者通过.CursorCursor.prototype.skip

2.x 语法:

const cursor = coll.find({ a: 42 }, { someField: 1 });
Run Code Online (Sandbox Code Playgroud)

3.x 语法:

const cursor = coll.find({ a: 42 }).project({ someField: 1 });

/* OR */

const cursor = coll.find({ a: 42 }, { projection: { someField: 1 } });
Run Code Online (Sandbox Code Playgroud)