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

the*_*rgo 36 mongodb mongodb-query aggregation-framework

是否可以重命名查找查询中返回的字段名称?我想使用类似的东西$rename,但我不想改变我正在访问的文件.我只想以不同的方式检索它们,就像SELECT COORINATES AS COORDS在SQL中一样.

我现在应该做什么:

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

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

Nei*_*unn 45

所以基本上使用.aggregate()而不是.find():

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

这可以为您提供所需的结果.

MongoDB 2.6及以上版本返回一个"游标",就像find一样.

有关详细信息,请参阅$project其他聚合框架运算符.


对于大多数情况,您只需重命名.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;
})
Run Code Online (Sandbox Code Playgroud)

或更多内联:

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

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


Abh*_*ash 7

我们知道,一般来说, $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
        }}
    ])
Run Code Online (Sandbox Code Playgroud)


Xav*_*hot 5

正如@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 ] }
Run Code Online (Sandbox Code Playgroud)

由于您提到findOne,您还可以将结果文档的数量限制为 1,如下所示:

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

之前Mongo 4.2和开始Mongo 3.4$replaceRoot可以用来代替$replaceWith

db.collection.aggregate(
  { $replaceRoot: { newRoot: { coords: "$level1.level2.coordinates" } } }
)
Run Code Online (Sandbox Code Playgroud)