在Field Projection中忽略batchSize字段名称

时间:2017-07-14 08:55:05

标签: javascript node.js mongodb

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

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

在查找查询中,我只想投影名称 batchSize 。但是当我从nodejs执行查询查询时,我在查询结果中获取整个文档。查询:

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

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

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

2 个答案:

答案 0 :(得分:7)

您是正确的,驱动程序错误地将此解释为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()

,第一个输出表单是更正后的表单

答案 1 :(得分: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.skipconst cursor = coll.find({ a: 42 }, { someField: 1 }); 方法添加它们。

2.x语法:

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

/* OR */

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

3.x语法:

public class MyCache extends HazelcastCacheManager {

    private final ConcurrentMap<String, Cache> myCaches = new ConcurrentHashMap<String, Cache>();

    public MyCache(){
        super();
    }


    public MyCache(HazelcastInstance hazelcastInstance){
        super(hazelcastInstance);
    }
    @Override
    public Cache getCache(String name) {

        String tenant = org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getName();
        Cache cache = myCaches.get(tenant.concat("#").concat(name));
        if (cache == null) {
            IMap<Object, Object> map = getHazelcastInstance().getMap(tenant.concat("#").concat(name));
            cache = new HazelcastCache(map);
            Cache currentCache = cesCaches.putIfAbsent(tenant.concat("#").concat(name), cache);
            if (currentCache != null) {
                cache = currentCache;
            }
        }

        return (Cache)cache;
    }