Select 子文档中数组的最后一个值
Select last value of array in sub document
我有以下文档结构
{
"_id" : 1,
"prices" : {
"100" : [
5.67,
.
.
1.7,
],
"101" : [
4.67,
.
.
1.4,
},
"v" : 2
}
我们需要使用 mongodb v3.0.2 从字段“100”和“101”中获取最后一个值,例如 1.7 和 1.4。目前我们正在加载整个文档,然后在应用程序中获取所需的值。它已经成为一个相当大的瓶颈,因为每个文档可能约为 1MB,这对于 100 多个文档来说是加起来的。
我们希望 mongodb 有一个合适的功能,使我们能够从文档中检索我们需要的数据,可能作为对每个价格字段的单独调用,即一次价格调用“100”键和第二次调用价格“101”键。
我们已经尝试使用 $slice 运算符,但遗憾的是它不能与排除字段一起使用,https://jira.mongodb.org/browse/SERVER-3378。
我们还看到了以下内容post:
How to combine both $slice and select returned keys operation in function update?
这几乎可以工作,但是查询中的 return 值:
db.account_articles.find({"_id" : ObjectId("1")}, { "prices.100" : { $slice: -1 }, "_id" : 1 })
是:
{
"_id" : 1,
"prices" : {
"100" : [
1.7
],
"101" : [
4.67,
.
.
1.4,
}
}
即已经完成了 90%,我们只需要能够排除“101”字段即可。
我们是不是遗漏了什么或者这在 monogodb 中是不可能的?
您需要聚合框架来执行此操作,我认为您确实应该更改结构,但请使用现有的:
Model.aggregate(
[
{ "$match": { "prices.100": { "$exists": true } }},
{ "$unwind": "$prices.100" },
{ "$group": {
"_id": "$_id",
"price": { "$last": "$prices.100" }
}},
{ "$project": { "_id": 0, "prices.100": "$price" } }
]
)
在未来的版本中,您将能够只使用新的 $slice
运算符:
Model.aggregate(
[
{ "$match": { "prices.100": { "$exists": true } } },
{ "$project": {
"_id": 0,
"prices.100": { "$slice": ["$prices.100",-1] }
}}
]
)
事实上你可以同时做"both"个字段:
Model.aggregate(
[
{ "$match": { "prices.100": { "$exists": true } } },
{ "$project": {
"_id": 0,
"prices.100": { "$slice": ["$prices.100",-1] },
"prices.101": { "$slice": ["$prices.100",-1] }
}}
]
)
这比使用 $unwind
and $last
to get the last element of the array when $group
处理以取回数据要好得多。
它基本上与新形式的常规查询具有相同的性能。在目前的形式下,速度会变慢。
您可以查看这个简单易行的解决方案。
只需获取数组项的最后一个索引即可。
我有以下文档结构
{
"_id" : 1,
"prices" : {
"100" : [
5.67,
.
.
1.7,
],
"101" : [
4.67,
.
.
1.4,
},
"v" : 2
}
我们需要使用 mongodb v3.0.2 从字段“100”和“101”中获取最后一个值,例如 1.7 和 1.4。目前我们正在加载整个文档,然后在应用程序中获取所需的值。它已经成为一个相当大的瓶颈,因为每个文档可能约为 1MB,这对于 100 多个文档来说是加起来的。
我们希望 mongodb 有一个合适的功能,使我们能够从文档中检索我们需要的数据,可能作为对每个价格字段的单独调用,即一次价格调用“100”键和第二次调用价格“101”键。
我们已经尝试使用 $slice 运算符,但遗憾的是它不能与排除字段一起使用,https://jira.mongodb.org/browse/SERVER-3378。
我们还看到了以下内容post: How to combine both $slice and select returned keys operation in function update?
这几乎可以工作,但是查询中的 return 值:
db.account_articles.find({"_id" : ObjectId("1")}, { "prices.100" : { $slice: -1 }, "_id" : 1 })
是:
{
"_id" : 1,
"prices" : {
"100" : [
1.7
],
"101" : [
4.67,
.
.
1.4,
}
}
即已经完成了 90%,我们只需要能够排除“101”字段即可。
我们是不是遗漏了什么或者这在 monogodb 中是不可能的?
您需要聚合框架来执行此操作,我认为您确实应该更改结构,但请使用现有的:
Model.aggregate(
[
{ "$match": { "prices.100": { "$exists": true } }},
{ "$unwind": "$prices.100" },
{ "$group": {
"_id": "$_id",
"price": { "$last": "$prices.100" }
}},
{ "$project": { "_id": 0, "prices.100": "$price" } }
]
)
在未来的版本中,您将能够只使用新的 $slice
运算符:
Model.aggregate(
[
{ "$match": { "prices.100": { "$exists": true } } },
{ "$project": {
"_id": 0,
"prices.100": { "$slice": ["$prices.100",-1] }
}}
]
)
事实上你可以同时做"both"个字段:
Model.aggregate(
[
{ "$match": { "prices.100": { "$exists": true } } },
{ "$project": {
"_id": 0,
"prices.100": { "$slice": ["$prices.100",-1] },
"prices.101": { "$slice": ["$prices.100",-1] }
}}
]
)
这比使用 $unwind
and $last
to get the last element of the array when $group
处理以取回数据要好得多。
它基本上与新形式的常规查询具有相同的性能。在目前的形式下,速度会变慢。
您可以查看这个简单易行的解决方案。
只需获取数组项的最后一个索引即可。