MongoDB$project嵌入到根级别的文档
MongoDB $project embedded document to root level
使用聚合管道,我尝试将嵌入式文档投影到根级别,而无需单独投影每个字段。
例如,我想将此集合中的name
投影到根级别:
[
{
_id: "1",
name: {
firstName: "John",
lastname: "Peters"
}
},
{
_id: "2",
name: {
firstName: "Mary",
lastname: "Jones"
}
}
]
这就是我正在寻找的:
[
{
firstName: "John",
lastname: "Peters"
},
{
firstName: "Mary",
lastname: "Jones"
}
]
有没有办法在不单独投影每个字段的情况下做到这一点?我不想这样做:
db.collection.aggregate(
[
{
$project : {
"_id" : 0,
"firstName" : "$name.firstName",
"lastName" : "$name.lastName"
}
}
]
MongoDB 3.4在聚合管道中具有新的阶段 - $replaceRoot
,它完全按照要求执行。
https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/
这是使用 JavaScript 变量的解决方案。
# Set Object for what to project
var projectWhat = {'_id' : 0};
# Fill Object with keys
Object.keys(db.coll.findOne().name).forEach(function(x){
projectWhat[x] = "$name." + x;
});
# Do Aggregate
db.coll.aggregate([{$project : projectWhat}])
输出将是
{ "firstName" : "John", "lastname" : "Peters" }
{ "firstName" : "Mary", "lastname" : "Jones" }
希望这有帮助。
你可以像这样使用$replaceRoot
:
db.collection.aggregate(
[
{
$replaceRoot : {
newRoot: {"$name"}
}
}
]
)
此外,如果根文档中有一个要保留的字段,则可以使用$mergeObjects
将其与嵌入对象组合:
db.collection.aggregate(
[
{
$replaceRoot : {
newRoot: {
$mergeObjects: [
{"_id": "$_id"},
"$name"
]
}
}
}
]
)
这可以
通过使用$set
使用name
子文档中的值更新所有文档来实现:
db.collection.find({ "name": {"$exists": 1 } }).forEach(function(doc) {
var setName = {};
for ( var k in doc.name ) {
setName[k] = doc.name[k];
}
db.collection.update(
{ "_id": doc._id },
{ "$set": setName, "$unset": "name" }
);
})
虽然我建议您使用 $project
因为它比此解决方案的性能更高,但我可以理解您为什么不想使用 $project
.
从Mongo 4.2
开始,$replaceWith
聚合运算符可用于将一个文档替换为另一个文档(在我们的例子中是子文档):
// { _id: "1", name: { firstName: "John", lastname: "Peters" } }
// { _id: "2", name: { firstName: "Mary", lastname: "Jones" } }
db.collection.aggregate({ $replaceWith: "$name" })
// { firstName: "John", lastname: "Peters" }
// { firstName: "Mary", lastname: "Jones" }
相关文章:
- 使用promise和mongoose对文档进行排序
- document.open/document.write没有正确地清除chrome中的文档——这是chrome的错误吗
- Ajax请求文档就绪会导致jquery加载缓慢
- MongoDB (php) - 以数组而不是多个属性的形式返回文档属性
- 谷歌文档表面引擎
- 来自文档或下一个静态父级的事件委派
- 如何将childNodes用于XML文档
- 文档就绪提供了错误的选择器高度
- 将当前用户的 ID 推送到 meteorjs 中集合/文档的内部数组
- 未捕获的语法错误:无法在“文档”上执行“查询选择器”
- BrowserId登录请求在文档加载时被调用
- 从Javascript和Php变量创建Html模板文档
- 如何通过谷歌应用程序脚本从谷歌文档中的位置确定命名范围
- 在jquery文档准备好之前加载Modernizr
- 如何判断何时将dom节点添加到文档中
- 无法获取文档.GetElementById工作正常
- 为什么是文档.旧版应用程序中的DOM-object.properties为null
- 有没有一种方法可以在没有文档或jQuery的情况下使用javascript解码html实体
- 是否存在Javascript Liferay Service库的文档?如何处理错误情况
- MongoDB$project嵌入到根级别的文档