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 处理以取回数据要好得多。

它基本上与新形式的常规查询具有相同的性能。在目前的形式下,速度会变慢。

您可以查看这个简单易行的解决方案。

只需获取数组项的最后一个索引即可。