【问题标题】:batchSize field name ignored in Field Projection字段投影中忽略的 batchSize 字段名称
【发布时间】:2017-12-19 07:19:52
【问题描述】:

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

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

在查找查询中,我只想投影 namebatchSize。但是当我从 nodejs 执行 find 查询时,我在查询结果中得到了整个文档。查询:

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

如果我只是通过 {name: 1} 那么它将投射 _id 和 name。但是如果我通过 batchSize 那么它将返回整个文档。

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

【问题讨论】:

  • 您使用的是哪个特定的节点驱动程序版本?只是想确认哪些版本受到影响。
  • 驱动版本 - 2.2.28,mongo - 3.2.14,节点 - 6.9.3

标签: javascript node.js mongodb


【解决方案1】:

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

在现代驱动程序版本中,正确的方法是实际使用.project()“光标方法”。这与其他语言驱动程序实现更加一致。

    db.collection('collection').find()
      .project({ name: 1, batchSize: 1})
      .toArray();

作为一个完整的演示:

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()
  }

})()

产生输出:

[
  {
    "_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": []
  }
]

第一个输出形式是更正后的形式,使用.project()

【讨论】:

    【解决方案2】:

    Find 的语法已更改。以下是解决此问题所需的知识。本文摘自https://github.com/mongodb/node-mongodb-native/blob/master/CHANGES_3.0.0.md#find

    查找

    findfindOne 不再支持 fields 参数。您可以获得与以下相同的结果 fields 参数,通过使用 Cursor.prototype.project 或通过传递 projection 属性 在选项对象上。此外,find 不支持像 skiplimit 作为位置参数。您必须在 options 对象中传递这些参数, 或通过Cursor 方法添加它们,例如Cursor.prototype.skip

    2.x 语法:

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

    3.x 语法:

    const cursor = coll.find({ a: 42 }).project({ someField: 1 });
    
    /* OR */
    
    const cursor = coll.find({ a: 42 }, { projection: { someField: 1 } });
    

    【讨论】:

      猜你喜欢
      • 2022-08-18
      • 2015-04-01
      • 2021-09-08
      • 2020-02-12
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 2015-04-19
      相关资源
      最近更新 更多