代码之家  ›  专栏  ›  技术社区  ›  Kavvson Empcraft

Laravel MongoDB-聚合、排序查询

  •  1
  • Kavvson Empcraft  · 技术社区  · 7 年前

    我想知道我怎样才能达到一个特定的结果。

    开始 我正在使用 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

    如果你真的需要更多的解释,尽管问,我觉得我甚至不知道从哪里开始这个。

    非常感谢您的帮助

    1 回复  |  直到 7 年前
        1
  •  1
  •   s7vr    7 年前

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

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

    $filter 弹头匹配奖励 example_slug 然后 $sum quantity

    $match 具有 $gt > 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]]]);
    });
    

    你可以替换 具有 estimated.value 用于第二次聚合。

    推荐文章