选择子文档

时间:2015-08-20 09:50:01

标签: mongodb mongodb-query aggregation-framework

我有以下文档结构

{ 
    "_id" : 1, 
    "prices" : { 
        "100" : [
                5.67,
                .
                .
                1.7,    
            ], 
        "101" : [
                4.67,
                .
                .
                1.4,  
    }, 
    "v" : 2 
}

我们需要从每个字段中获取最后一个值" 100"和" 101",例如1.7& 1.4,使用mongodb v3.0.2。目前我们正在加载整个文档,然后在应用程序中获取所需的值。它已经成为一个瓶颈,因为每个文档可能大约1MB,这对于100个文档来说是累加的。

我们希望有一个合适的mongodb功能,它允许我们从文档中检索我们需要的数据,可能作为每个价格字段的单独调用,即一次调用价格" 100&# 34;关键和第二次调用价格" 101"键。

我们已尝试使用$ slice运算符,但遗憾的是,这不能用于排除字段https://jira.mongodb.org/browse/SERVER-3378

我们还看到了以下帖子: How to combine both $slice and select returned keys operation in function update?

这几乎可以,但查询的返回值:

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中这是不可能的?

2 个答案:

答案 0 :(得分:2)

你需要聚合框架才能做到这一点,我认为你真的应该改变结构,但是要使用你拥有的东西:

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] }
        }}
    ]
)

事实上,您可以同时执行“两个”字段:

Model.aggregate(
    [
        { "$match": { "prices.100": { "$exists": true } } },
        { "$project": {
            "_id": 0,
            "prices.100": { "$slice": ["$prices.100",-1] },
            "prices.101": { "$slice": ["$prices.100",-1] }
        }}
    ]
)

这比使用$unwind$last进行处理要好得多,以便在应用$group来获取数据时获取数组的最后一个元素。

它基本上具有与较新表单中的常规查询相同的性能。在目前的形式中,它会变慢。

答案 1 :(得分:0)

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

Return latest record from subdocument in Mongodb

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