Mongoose最佳查询 - 对两个属性进行排序

时间:2015-06-13 07:05:39

标签: javascript mongodb

示例mongodb记录:

[
    {first: "Some", middle: "A", last: ""},
    {first: "Some", middle: "B", last: ""},
    {first: "Some", middle: "", last: "C"},
    {first: "Some", middle: "D", last: ""}
]         

输出:

If .sort({middle:1,last:1})  =====> C,A,B,D
If .sort({last:1, middle:1}) =====> A,B,D,C
If [what here ? ]            =====> A,B,C,D

3 个答案:

答案 0 :(得分:1)

您的问题是您尝试对两个字段进行排序,如果另一个字段不为空,则使用一个字段。没有简单的排序可以提供,因为它总是按一个字段然后另一个字段排序。

您需要将此作为多步查询执行此操作。首先获取数据并生成一个新的字段,对包含last的内容进行排序,如果last为空,则使用middle。然后对那个新领域进行排序。

这会使索引相当无用,因此对于大型数据集来说性能会很差。

更好的方法是更正您的数据,而不是使用空白姓氏保存。如果姓氏为空,则将中间名移至姓氏。

答案 1 :(得分:1)

我找到了这个解决方案。

// AppKernel.php
if (in_array($this->getEnvironment(), ['dev', 'test'])) {
    ...
    $bundles[] = new \Symfony\Bundle\DebugBundle\DebugBundle();
}

*****

// usage:
public function testSomeAction()
{
    .....
    $response = $client->getResponse();
    dump($response);
    die;
}

答案 2 :(得分:1)

您可以使用aggregation framework将数据转换为表单,您可以按照自己的方式sort将其转换为表单。试试这个聚合查询:

db.yourCollection.aggregate(
    [
        {$project: 
            {
                first: 1, 
                rest: {$cond: [{$eq: ['$middle', '']}, 
                '$last', '$middle']}, 
                isMiddle: {$cond: [{$eq: ['$middle', '']}, false, true]}
            }
        }, 
        {$sort: {rest: 1}}, 
        {$project: 
            {
                first: 1, 
                middle: {$cond: ['$isMiddle', '$rest', '']}, 
                last: {$cond: ['$isMiddle', '', '$rest']}
            }
        }
    ]
)

这样可以得到你想要的东西:

{ "first" : "Some", "middle" : "A", "last" : "" }
{ "first" : "Some", "middle" : "B", "last" : "" }
{ "first" : "Some", "middle" : "", "last" : "C" }
{ "first" : "Some", "middle" : "D", "last" : "" }

常规排序的问题是middlelast是单独的键并且是独立排序的(虽然稳定)。因此,实现目标的唯一方法是将它们组合在一个密钥中。