gpt4 book ai didi

mongodb - 使用 Golang mgo.v2 的嵌套 MongoDB 查询

转载 作者:IT王子 更新时间:2023-10-29 01:05:24 28 4
gpt4 key购买 nike

我正在查询一个包含嵌套项目数组的 json 结构。我想返回整个结构,但只包括符合查询条件的嵌套项目。

所以 - 样本结构是

{
parentId:1,
items: [
{
field1: 1
field2: 2
},
{
field1: 3
field2: 4
}
]
}

我想查询这样的东西->

db.getCollection('mycollection').find({"items.field1":1, "items.field2":2}) 

这行得通,但它也带回了第二个子项,我希望它实际返回的是这个 ->

{
parentId:1,
items: [
{
field1: 1
field2: 2
}
]
}

我已经能够在 MongoDB 本身中创建一个查询,它实现了我想要的 ->

db.getCollection('mycollection').aggregate(
{ $unwind : "$items" },
{ $match : {
"items.field1": 1,
"items.field2": 2,
}}
)

但是当尝试使用 mgo.v2 进行设置时,它被证明有点困难。 collection.Find 方法似乎不喜欢 $unwind 命令,并且似乎无法获得正确的语法来使其与 Pipe 方法一起使用。

有人对如何创建它有任何建议吗?我可以只创建字符串并将其传递给执行吗?

最佳答案

您需要的实际管道涉及使用 $filter 运算符,它根据指定的条件选择要返回的数组的子集。它返回一个仅包含与条件匹配的元素的数组。

在您的情况下,您需要运行以下聚合操作

db.mycollection.aggregate([
{
"$project": {
"parentId": 1,
"items": {
"$filter": {
"input": "$items",
"as": "item",
"cond": {
"$and": [
{ "$eq": ["$$item.field1", 1] },
{ "$eq": ["$$item.field2", 2] }
]
}
}
}
}
}
])

测试 enter image description here


对于不支持 $filter 的 MongoDB 版本 运算符,您可以使用 set operators 的组合作为:

db.mycollection.aggregate([
{
"$project": {
"parentId": 1,
"items": {
"$setDifference": [
{ "$map": {
"input": "$items",
"as": "item",
"in": {
"$cond": [
{
"$and": [
{ "$eq": ["$$item.field1", 1] },
{ "$eq": ["$$item.field2", 2] }
]
},
"$$item",
false
]
}
}},
[false]
]
}
}
}
])

作为最后的手段,您可以使用 $unwind 运算符作为运算符为每个数组条目生成每个文档的副本,它使用更多内存(聚合管道上可能的内存上限为总内存的 10%),因此也需要时间来生成以及“时间”来处理。您可以运行为:

db.mycollection.aggregate([
{ "$unwind" : "$items" },
{ "$match" : {
"items.field1": 1,
"items.field2": 2,
}},
{
"$group": {
"_id": "$_id",
"parentId": { "$first": "$parentId" },
"items": { "$push": "$items" }
}
}
])

您可以在 mgo 中将其作为 pipeline 运行:

pipeline := []bson.M{   
bson.M{ "$unwind": "$items" },
bson.M{
"$match": bson.M{
"items.field1": 1,
"items.field2": 2
}
},
bson.M{
"$group": bson.M{
"_id": "$_id",
"parentId": bson.M{ "$first": "$parentId" },
"items": bson.M{ "$push": "$items" }
}
}
}
pipe := mycollection.Pipe(pipeline)
iter := pipe.Iter()

在 Robomongo 中测试

enter image description here

关于mongodb - 使用 Golang mgo.v2 的嵌套 MongoDB 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39512394/

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