gpt4 book ai didi

mongodb - mongo $unwind 和 $group

转载 作者:IT老高 更新时间:2023-10-28 13:32:02 28 4
gpt4 key购买 nike

我有两个系列。其中一个我希望添加对另一个的引用并在返回时填充它。

这是我试图实现的示例 json:

{
"title": "Some Title",
"uid": "some-title",
"created_at": "1412159926",
"updated_at": "1412159926",
"id": "1",
"metadata": {
"date": "2016-10-17",
"description": "a description"
},
"tags": [
{
"name": "Tag 1",
"uid": "tag-1"
},
{
"name": "Tag 2",
"uid": "tag-2"
},
{
"name": "Tag 3",
"uid": "tag-3"
}
]
}

这是我的 mongo 查询,它让我很接近,但它将项目的原始主体嵌套在 _id 对象中。

db.tracks.aggregate([{
$unwind: "$tags"
}, {
$lookup: {
from: "tags",
localField: "tags",
foreignField: "_id",
as: "tags"
}
}, {
$unwind: "$tags"
}, {
$group: {
"_id": {
"title": "$title",
"uid": "$uid",
"metadata": "$metadata"
},
"tags": {
"$push": "$tags"
}
}
}])

所以结果是这样的:

{
"_id" : {
"title" : "Some Title",
"uid" : "some-title",
"metadata" : {
"date" : "2016-10-17",
"description" : "a description"
}
},
"tags" : [
{
"_id" : ObjectId("580499d06fe29ce7093fb53a"),
"name" : "Tag 1",
"uid" : "tag-1"
},
{
"_id" : ObjectId("580499d06fe29ce7093fb53b"),
"name" : "Tag 2",
"uid" : "tag-2"
}
]
}

有没有办法实现所需的输出?还有一种方法不必在 $group 中定义我希望返回的所有字段,我想返回原始对象,但在 tags 数组。

最佳答案

由于您最初在 tags 数组字段中旋转了原始文档,这意味着文档将被非规范化,因此您的 $group 管道应该使用 _id 字段作为其 _id 键并使用 $first 访问其他字段 $last 运算符。

组管道运算符类似于 SQL 的 GROUP BY 子句。在 SQL 中,您不能使用 GROUP BY,除非您使用任何聚合函数。同样,我们也必须在 MongoDB 中使用聚合函数,所以不幸的是,没有其他方法可以不必在 $group 中定义。 管道除了使用 $first 之外,您希望返回的所有字段 $last每个字段的 运算符:

db.tracks.aggregate([
{ "$unwind": "$tags" },
{
"$lookup": {
"from": "tags",
"localField": "tags",
"foreignField": "_id",
"as": "resultingArray"
}
},
{ "$unwind": "$resultingArray" },
{
"$group": {
"_id": "$_id",
"title": { "$first": "$title" },
"uid": { "$first": "$uid" },
"created_at": { "$first": "$created_at" },
"updated_at": { "$first": "$updated_at" },
"id": { "$first": "$id" },
"metadata": { "$first": "$metadata" },
"tags": { "$push": "$resultingArray" }
}
}
])

每当我想调试产生意外结果的管道时,我总是使用的一个技巧是仅使用第一个管道运算符运行聚合。如果这给出了预期的结果,请添加下一个。

在上面的答案中,您首先尝试仅聚合 $unwind ;如果可行,请添加 $lookup 。这可以帮助您缩小导致问题的运营商的范围。在这种情况下,您可以只用前三个步骤运行管道,因为您相信 $group 是导致问题的原因,然后检查来自该管道的结果文档:

db.tracks.aggregate([
{ "$unwind": "$tags" },
{
"$lookup": {
"from": "tags",
"localField": "tags",
"foreignField": "_id",
"as": "resultingArray"
}
},
{ "$unwind": "$resultingArray" }
])

产生输出

/* 1 */
{
"_id" : ObjectId("5804a6c900ce8cbd028523d9"),
"title" : "Some Title",
"uid" : "some-title",
"created_at" : "1412159926",
"updated_at" : "1412159926",
"id" : "1",
"metadata" : {
"date" : "2016-10-17",
"description" : "a description"
},
"resultingArray" : {
"name" : "Tag 1",
"uid" : "tag-1"
}
}

/* 2 */
{
"_id" : ObjectId("5804a6c900ce8cbd028523d9"),
"title" : "Some Title",
"uid" : "some-title",
"created_at" : "1412159926",
"updated_at" : "1412159926",
"id" : "1",
"metadata" : {
"date" : "2016-10-17",
"description" : "a description"
},
"resultingArray" : {
"name" : "Tag 2",
"uid" : "tag-2"
}
}

/* 3 */
{
"_id" : ObjectId("5804a6c900ce8cbd028523d9"),
"title" : "Some Title",
"uid" : "some-title",
"created_at" : "1412159926",
"updated_at" : "1412159926",
"id" : "1",
"metadata" : {
"date" : "2016-10-17",
"description" : "a description"
},
"resultingArray" : {
"name" : "Tag 3",
"uid" : "tag-3"
}
}

通过检查您会看到,对于每个输入文档,最后一个管道输出 3 个文档,其中 3 是计算字段 resultingArray 中数组元素的数量,它们都有一个共同的 _id 和除 resultingArray 字段之外的其他字段不同,因此您可以通过添加按 _id 对文档进行分组的管道来获得所需的结果字段,然后使用 $first 获取其他字段 $last 运算符,如给定的解决方案:

db.tracks.aggregate([
{ "$unwind": "$tags" },
{
"$lookup": {
"from": "tags",
"localField": "tags",
"foreignField": "_id",
"as": "resultingArray"
}
},
{ "$unwind": "$resultingArray" },
{
"$group": {
"_id": "$_id",
"title": { "$first": "$title" },
"uid": { "$first": "$uid" },
"created_at": { "$first": "$created_at" },
"updated_at": { "$first": "$updated_at" },
"id": { "$first": "$id" },
"metadata": { "$first": "$metadata" },
"tags": { "$push": "$resultingArray" }
}
}
])

关于mongodb - mongo $unwind 和 $group,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40083592/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com