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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23784370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 13:43:29  来源:igfitidea点击:

How do I rename fields when performing search/projection in MongoDB?

mongodbmongodb-queryaggregation-framework

提问by themiurgo

Is it possible to rename the name of fields returned in a find query? I would like to use something like $rename, however I wouldn't like to change the documents I'm accessing. I want just to retrieve them differently, something that works like SELECT COORINATES AS COORDSin SQL.

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

What I do now:

我现在应该做什么:

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

What I would like to be returned is: {'coords': [10, 20]}

我想被退回的是: {'coords': [10, 20]}

回答by Neil Lunn

So basically using .aggregate()instead of .find():

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

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

And that gives you the result that you want.

这会给你你想要的结果。

MongoDB 2.6 and above versions return a "cursor" just like find does.

MongoDB 2.6 及以上版本返回一个“游标”,就像 find 一样。

See $projectand other aggregation framework operatorsfor more details.

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



For most cases you should simply rename the fields as returned from .find()when processing the cursor. For JavaScript as an example, you can use .map()to do this.

在大多数情况下,您应该简单地重命名.find()处理游标时返回的字段。以 JavaScript 为例,您可以使用它.map()来执行此操作。

From the shell:

从外壳:

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

Or more inline:

或更多内联:

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

This avoids any additional overhead on the server and should be used in such cases where the additional processing overhead would outweigh the gain of actual reduction in size of the data retrieved. In this case ( and most ) it would be minimal and therefore better to re-process the cursor result to restructure.

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

回答by Xavier Guihot

As mentioned by @Neil Lunn this can be achieved with an aggregation pipeline:

正如@Neil Lunn 所提到的,这可以通过聚合管道来实现:

And starting Mongo 4.2, the $replaceWithaggregation operator can be used to replace a document by a sub-document:

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

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

Since you mention findOne, you can also limit the number of resulting documents to 1 as such:

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

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

Prior to Mongo 4.2and starting Mongo 3.4, $replaceRootcan be used in place of $replaceWith:

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

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

回答by Kokkonda Abhilash

As we know, in general, $project stage takes the field names and specifies 1 or 0/true or false to include the fields in the output or not, we also can specify the value against a field instead of true or false to rename the field. Below is the syntax

正如我们所知,一般来说,$project stage 获取字段名称并指定 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 to renames the field.
            totalCount: true
        }}
    ])

回答by Kevin Fairclough

Stages (>= 4.2)

阶段 (>= 4.2)

  • $addFields : {"New": "$Old"}
  • $unset : {"$Old": 1}
  • $addFields : {"New": "$Old"}
  • $unset : {"$Old": 1}