【问题标题】:How do I sum multiple fields in doctrine odm?如何对学说 odm 中的多个字段求和?
【发布时间】:2017-11-23 17:03:48
【问题描述】:

我想使用学说 odm 的聚合构建器来构建这个查询:

db.TeamStandings.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $match: {
                "team.$id": ObjectId("5a1643fdf5d8741a883c2aeb")
            }
        },

        // Stage 2
        {
            $group: {
                "_id": { "team": "team.$id" },

                // This is the sum of multiple fields
                "games": { $sum: { $sum: ["$wins", "$losses", "$ties"] } }, 

                "wins": { $sum: "$wins" },
                "losses": { $sum: "$losses" },
                "ties": { $sum: "$ties" },
                "homeWins" : { $sum: "$homeRecord.wins" },
                "homeLosses" : { $sum: "$homeRecord.losses" },
                "homeTies" : { $sum: "$homeRecord.ties" },
                "roadWins" : { $sum: "$roadRecord.wins" },
                "roadLosses" : { $sum: "$roadRecord.losses" },
                "roadTies" : { $sum: "$roadRecord.ties" },
            }
        },

    ]
);

我在 Studio3T 中执行了这个,得到了以下结果:

{ 
    "_id" : {
        "team" : "team.$id"
    }, 
    "games" : NumberInt(776), 
    "wins" : NumberInt(377), 
    "losses" : NumberInt(398), 
    "ties" : NumberInt(1), 
    "homeWins" : NumberInt(218), 
    "homeLosses" : NumberInt(170), 
    "homeTies" : NumberInt(1), 
    "roadWins" : NumberInt(159), 
    "roadLosses" : NumberInt(228), 
    "roadTies" : NumberInt(0)
}

我如何使用教义 odm 的聚合构建器编写这个精确的查询?

【问题讨论】:

  • 关于聚合构建器的文档非常丰富:docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/…
  • 信不信由你,我去过那个页面很多次了。这就是我开始使用聚合生成器的方式。但是,我没有看到它涵盖了将多个字段加在一起的地方。我正在寻找的具体案例是如何在学说 odm 中写这个:"games": { $sum: { $sum: ["$wins", "$losses", "$ties"] } },
  • 在挖掘了学说 odm sum() 代码后,文档块说:Calculates and returns the sum of all the numeric values that result from applying a specified expression to each document in a group of documents that share the same group by key. Ignores nun-numeric values. 但它似乎 没有;或者更可能我不了解聚合构建器。
  • 您可能想要更新问题以说明您在 ODM 方面遇到的问题 - 到目前为止,它看起来像“我还没有尝试过,但请将此查询重写为 PHP”

标签: php doctrine doctrine-odm


【解决方案1】:

这个很棘手,因为文档不是很清楚。

理论上,您可以创建一个嵌套子表达式并在其中使用求和运算符:

$builder = $this->dm->createAggregationBuilder(\Documents\BlogPost::class);
$builder->group()
    ->field('id')
    ->expression(null)
    ->field('games')
    ->sum($builder->expr()->sum('$wins', '$losses', '$ties'))
;

但是,由于聚合构建器的构建方式,它不太理解 syntax$project 阶段之外的多个表达式的总和,导致以下(错误)结果:

[{
    "$group": {
        "_id": null,
        "games": { "$sum": { "$sum": "$wins" } }
    }
}]

要解决此问题,请在嵌套表达式中使用 $add 运算符而不是 $sum

$builder = $this->dm->createAggregationBuilder(\Documents\BlogPost::class);
$builder->group()
    ->field('id')
    ->expression(null)
    ->field('games')
    ->sum($builder->expr()->add('$wins', '$losses', '$ties'))
;

这将创建您希望它创建的聚合管道。

这很奇怪的原因是因为文档定义了$sum$group$project 阶段使用时的不同行为:在$group 中,它接受一个参数,而在$project 中它接受多个论据。但是,尚不清楚它在 $group 内的嵌套表达式中的行为方式:您发布的聚合管道有效的事实表明它没有将子表达式视为在 $group 阶段内,因此允许多个论点。当我构建运算符时,我假设相反:只有在 $project 阶段,$sum 才应该接受多个参数,否则默认为一个参数语法。

我将在 MongoDB ODM 中为此创建一个票证,看看是否可以轻松修复。

【讨论】:

猜你喜欢
  • 2016-12-21
  • 2016-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多