gpt4 book ai didi

MongoDB 对特定嵌套属性的投影

转载 作者:可可西里 更新时间:2023-11-01 10:38:07 25 4
gpt4 key购买 nike

"data" : {
"visits" : {
"daily" : {
"2018-09-05" : 3586,
"2018-09-06" : 2969,
"2018-09-07" : 2624,
"2018-09-08" : 2803,
"2018-09-09" : 3439,
"2018-09-10" : 3655
}
}
},

我在 MongoDB 中有这样的属性结构,我想做的是,如果我有开始日期和结束日期,例如 (2018-09-06 - 2018-09-07),我想得到这种格式的结果

"data" : {
"visits" : {
"daily" : {
"2018-09-06" : 2969,
"2018-09-07" : 2624
}
}
},

有什么有效的方法可以动态地做到这一点吗?我可以通过放入像这样的预测来做到这一点 {"data.visits.daily.2018-09-06": 1, "data.visits.daily.2018-09-07": 1} 它有效,但它没有在我看来这是一个很好的解决方案。

最佳答案

使用 MongoDB 3.4.4 和更新版本:

db.collection.aggregate([
{ "$addFields": {
"data.visits.daily": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$data.visits.daily" },
"as": "el",
"cond": {
"$and": [
{ "$gte": ["$$el.k", "2018-09-06"] },
{ "$lte": ["$$el.k", "2018-09-07"] },
]
}
}
}
}
} }
])

上面的管道将产生最终的输出

{
"data" : {
"visits" : {
"daily" : {
"2018-09-06" : 2969,
"2018-09-07" : 2624
}
}
}
}

说明

可以分解管道以显示每个单独的运算符的结果。

$objectToArray

$objectToArray 使您能够使用动态键转换文档到一个数组中,该数组包含原始文档中每个字段/值对的元素。返回数组中的每个元素都是一个包含两个字段 k 和 v 的文档。

$project 中仅与运算符(operator)一起运行管道阶段

db.collection.aggregate([
{ "$project": {
"keys": { "$objectToArray": "$data.visits.daily" }
} }
])

产量

{
"_id" : ObjectId("5bab6d09b1951fef20a5dce4"),
"keys" : [
{
"k" : "2018-09-05",
"v" : 3586
},
{
"k" : "2018-09-06",
"v" : 2969
},
{
"k" : "2018-09-07",
"v" : 2624
},
{
"k" : "2018-09-08",
"v" : 2803
},
{
"k" : "2018-09-09",
"v" : 3439
},
{
"k" : "2018-09-10",
"v" : 3655
}
]
}

$filter

$filter 运算符充当由 $objectToArray 生成的数组的过滤机制。 运算符,通过选择数组的一个子集来根据指定的条件返回成为您的查询。

考虑以下管道,它返回与条件 "2018-09-06" <= key <= "2018-09-07" 匹配的键/值对数组。

db.collection.aggregate([
{ "$project": {
"keys": {
"$filter": {
"input": { "$objectToArray": "$data.visits.daily" },
"as": "el",
"cond": {
"$and": [
{ "$gte": ["$$el.k", "2018-09-06"] },
{ "$lte": ["$$el.k", "2018-09-07"] },
]
}
}
}
} }
])

产生

{
"_id" : ObjectId("5bab6d09b1951fef20a5dce4"),
"keys" : [
{
"k" : "2018-09-06",
"v" : 2969
},
{
"k" : "2018-09-07",
"v" : 2624
}
]
}

$arrayToObject

这将从上面的过滤数组转换

[ 
{
"k" : "2018-09-06",
"v" : 2969
},
{
"k" : "2018-09-07",
"v" : 2624
}
]

使用动态 key 到原始文档

{
"2018-09-06" : 2969,
"2018-09-07" : 2624
}

所以运行管道

db.collection.aggregate([
{ "$project": {
"keys": {
"$arrayToObject": {
"$filter": {
"input": { "$objectToArray": "$data.visits.daily" },
"as": "el",
"cond": {
"$and": [
{ "$gte": ["$$el.k", "2018-09-06"] },
{ "$lte": ["$$el.k", "2018-09-07"] },
]
}
}
}
}
} }
])

会产生

{
"_id" : ObjectId("5bab6d09b1951fef20a5dce4"),
"keys" : {
"2018-09-06" : 2969,
"2018-09-07" : 2624
}
}

但是您当然希望保留原始模式,即当前字段,因此您需要使用 $addFields 而不是 $project 用于插图的管道。

$addFields

这相当于一个 $project 阶段明确指定输入文档中的所有现有字段并添加新字段。在 中指定现有字段名称 $addFields 操作会导致原始字段被替换,您需要使用点符号来使用动态键更新嵌入的 data.visits.daily 字段。

关于MongoDB 对特定嵌套属性的投影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52514800/

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