MongoDB获取所有字段+按多个字段计算的值排序

时间:2013-12-14 15:43:01

标签: mongodb aggregation-framework

我需要从MongoDB中的集合中获取文档。单个文档如下所示:

{
    name    : "John Doe",
    address : "Some cool address",
    value1  : 2,
    value2  : 3,
    value3  : 5
}

我需要检索所有字段,然后按照等于value1 + value2 + value3的数字对文档进行排序。

我找到的解决方案(不完整,因为它不检索所有字段)如下所示:

db.someCollection.aggregate(
    {
        $project: {
            sum: { $add: [ "$value1", "$value2", "$value3" ] }
        },
        $sort: {
            sum: -1
        }
    }
)

就像我说的,这只返回sum字段,这不是我想要的。

编辑:此外文档实际上有点大,所以我不想使用伪解决方案

$project: {
    name:    1,
    address: 1,
    ...
}

即。我想要一些通用的可重用解决方案,而不是特定于案例的解决方案

4 个答案:

答案 0 :(得分:7)

您可以使用$$ROOT来引用根文档。将此文档的所有字段保留在一个字段中,然后尝试获取它(取决于您的客户端系统:Java,C ++,...)

db.someCollection.aggregate(
    {
        $project: {
            sum: { $add: [ "$value1", "$value2", "$value3" ] },
            document: "$$ROOT"
        },
        $sort: {
            sum: -1
        }
    }
)

答案 1 :(得分:4)

尝试以下查询:

db.myCollection.aggregate(
{$project: {name : "$name", 
            address : "$address", 
            value1 : "$value1", 
            value2 : "$value2", 
            value3 : "$value3",
            sum : {$add : ["$value1", "$value2", "$value3"]}}},
{$sort: {sum: -1}}
)

据我所知,没有像MongoDB中的条件排序那样的选项。此外,默认情况下,没有选项可以将所有字段添加到项目中。这有一个问题,但尚未解决。

现在,另一种选择是创建新字段(例如:totalValues)并将该总和存储在该字段中以及值字段更改时。然后你可以按totalValues排序。

答案 2 :(得分:2)

其中$ project:需要指定要传递的字段,$ addFields将返回所有字段并添加或替换指定的字段。

db.someCollection.aggregate(
    {
        $addFields: {
            sum: { $add: [ "$value1", "$value2", "$value3" ] }
        },
        $sort: {
            sum: -1
        }
    }
)

将完全达到你想要的效果。

请注意,此功能已在Mongo 3.4版中添加。

答案 3 :(得分:0)

要取回数据库中的文档,您可以使用 $replaceRoot 运算符:

db.someCollection.aggregate(
    [
        {
            $project: {
                sum: { $add: [ "$value1", "$value2", "$value3" ] },
                document: "$$ROOT"
            }
        },
        {
            $sort: { sum: -1 }
        },
        {
            $replaceRoot : {newRoot : "$document"}
        }
    ]
)

结果是:

{
    "_id" : ObjectId("58f0d4777bde783e55e3410b"),
    "name" : "John Doe",
    "address" : "Some cool address",
    "value1" : 2,
    "value2" : 3,
    "value3" : 5
}

{
    "_id" : ObjectId("58f0d4c77bde783e55e3411e"),
    "name" : "Jane Doe",
    "address" : "Some cool address",
    "value1" : 1,
    "value2" : 3,
    "value3" : 2
}