在MongoDB中执行搜索/投影时如何重命名字段?

时间:2014-05-21 13:18:00

标签: mongodb mongodb-query aggregation-framework

是否可以重命名查找查询中返回的字段名称?我想使用类似$rename的内容,但我不想更改我访问的文档。我只想以不同方式检索它们,这类似于SQL中的SELECT COORINATES AS COORDS

我现在做的事情:

db.tweets.findOne({}, {'level1.level2.coordinates': 1, _id:0})
{'level1': {'level2': {'coordinates': [10, 20]}}}

我想要归还的是: {'coords': [10, 20]}

4 个答案:

答案 0 :(得分:41)

所以基本上使用.aggregate()代替.find()

db.tweets.aggregate([
    { "$project": {
        "_id": 0,
        "coords": "$level1.level2.coordinates"
    }}
])

这样就可以得到你想要的结果。

MongoDB 2.6及以上版本返回一个"游标"就像发现一样。

有关详细信息,请参阅$project和其他aggregation framework operators


对于大多数情况,您只需在处理光标时重命名从.find()返回的字段。以JavaScript为例,您可以使用.map()来执行此操作。

来自shell:

db.tweets.find({},{'level1.level2.coordinates': 1, _id:0}).map( doc => {
  doc.coords = doc['level1']['level2'].coordinates;
  delete doc['level1'];
  return doc;
})

或更多内联:

db.tweets.find({},{'level1.level2.coordinates': 1, _id:0}).map( doc => 
  ({ coords: doc['level1']['level2'].coordinates })
)

这可以避免服务器上的任何额外开销,并且应该在额外的处理开销超过所检索数据的实际减小量的情况下使用。在这种情况下(和大多数情况下)它将是最小的,因此最好重新处理游标结果以进行重组。

答案 1 :(得分:2)

我们知道,通常$ project阶段采用字段名称并指定1或0 / true或false以在输出中包含字段,我们也可以针对字段指定值,而不是true或false重命名字段。下面是语法

    db.test_collection.aggregate([
        {$group: {
            _id: '$field_to_group',
            totalCount: {$sum: 1}
        }},
        {$project: {
            _id: false,
            renamed_field: '$_id',    // here assigning a value instead of 0 or 1 / true or false effectively renames the field.
            totalCount: true
        }}
    ])

答案 2 :(得分:0)

如@Neil Lunn所述,这可以通过聚合管道来实现:

Mongo 4.2开始,$replaceWith聚合运算符可用于用子文档替换文档:

// { level1: { level2: { coordinates: [10, 20] }, b: 4 }, a: 3 }
db.collection.aggregate(
  { $replaceWith: { coords: "$level1.level2.coordinates" } }
)
// { "coords" : [ 10, 20 ] }

由于提到了findOne,因此您还可以将生成的文档数限制为1:

db.collection.aggregate([
  { $replaceWith: { coords: "$level1.level2.coordinates" } },
  { $limit: 1 }
])

Mongo 4.2之前并以Mongo 3.4开头,$replaceRoot可以代替$replaceWith

db.collection.aggregate(
  { $replaceRoot: { newRoot: { coords: "$level1.level2.coordinates" } } }
)

答案 3 :(得分:-2)

阶段(> = 4.2)

  • $ addFields:{“ New”:“ $ Old”}
  • $ unset:{“ $ Old”:1}