【问题标题】:Laravel MongoDB - aggregation, ordering queryLaravel MongoDB - 聚合、排序查询
【发布时间】:2019-04-12 07:16:05
【问题描述】:

我想知道如何才能达到特定的结果。

开始 我正在使用https://github.com/jenssegers/laravel-mongodb

下面的代码示例用于获取包含我在奖励节点中的特定 slug 的文档数组。直到那时,一切都按预期进行。

 $array = [
            'rewards.slug' => ['$eq' => 'example_slug'],
            'expired' => ['$gte' => \Carbon\Carbon::now()->toDateTimeString()]
        ];
        $models = Master::raw(function ($collection) use (&$array) {
            return $collection->find(
                $array, ["typeMap" => ['root' => 'array', 'document' => 'array']])
                ->toArray();
        });

我的示例文档

{
    "_id": {
        "$oid": "5be4464eafad20007245543f"
    },
    "some_int_value": 100,
    "some_string_value": "String",
    "rewards": [
        {
            "slug": "example_slug",
            "name": "Example slug",
            "quantity": 4,
            "estimated": {
                "value": 18750
            }
        },
        {
            "slug": "example_slug",
            "name": "Example slug",
            "quantity": 1,
            "estimated": {
                "value": 100
            }
        },
        {
            "slug": "other_example",
            "name": "Other slug example",
            "quantity": 1,
            "estimated": {
                "value": 100
            }
        }
    ],
    "expires": "2018-11-08 20:20:45",
}

想要的结果

我想实现一些更复杂的查询,它将执行以下操作。

  • 检索以下文档:伪select all documents that contain reward "slug": "example_slug", sum the quantity of them, return greater than X quantity documents, order by sum quantity desc
  • 和上面一个非常相似的select all documents that contain reward "slug": "example_slug", sum estimated.value, return greater than X estimated.value documents, order by sum of estimated.value desc

如果您确实需要更多解释,请随时询问,我觉得我什至不知道从哪里开始。

非常感谢所有帮助

【问题讨论】:

    标签: mongodb laravel laravel-5 aggregation-framework jenssegers-mongodb


    【解决方案1】:

    您可以在 3.6 中使用以下聚合。

    $addFields 创建一个额外的 slugcount 字段来保存结果。

    $filter 奖励与 slug 匹配 example_slug 后跟 $sum 以求和 quantity 字段。

    $match$gt > X - 用于过滤所有匹配数量之和大于 X 的文档的聚合表达式

    $sort slugcount desc 和 $project 排除以从最终响应中删除 slugcount。

    db.colname.aggregate([
    {"$addFields":{
      "slugcount":
       {"$let":{
        "vars":{
         "mslug":{
          "$filter":{
           "input":"$rewards",
           "cond":{"$eq":["$$this.slug","example_slug"]}
          }
         }
        },
        "in":{"$sum":"$$mslug.quantity"}
        }}
    }}, 
    {"$match":{"slugcount":{"$gt":X}}},
    {"$sort":{"slugcount":-1}},
    {"$project":{"slugcount":0}}
    ])
    

    有点像

    ModelName::raw(function ($collection) {
     return $collection->aggregate([
      ['$match' => ['expired' => ['$gte' => \Carbon\Carbon::now()->toDateTimeString()]]],
      ['$addFields' => [
        'slugcount'
         ['$let' => [
          'vars' => [
           'mslug' => [
            '$filter' => [
             'input' => '$rewards',
             'cond' => ['$eq' => ['$$this.slug','example_slug']]
            ]
           ]
          ],
          'in' => ['$sum' => '$$mslug.quantity']
          ]]
      ]],
      ['$match' => ['slugcount'=> ['$gt' => X]]],
      ['$sort' => ['slugcount' => -1]],
      ['$project' => ['slugcount' => 0]]]);
    });
    

    您可以将quantity 替换为estimated.value 以进行第二次聚合。

    【讨论】:

    • 你想要那些单引号的操作符,是吗?例如'$gt' 不是"$gt"
    • 很快就会看看 :)
    • 我觉得我们错过了 '$gte' => \Carbon\Carbon::now()->toDateTimeString() 否则它似乎是正确的,你能用那个更新答案吗:)
    • 嘿 Veeram,是否可以返回计算值(我假设为 $match 值)并将其附加到结果中? (不作为数据库更新)
    猜你喜欢
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多