MongoDB находит документы, которые соответствуют регулярному выражению и имеют самую большую цену - PullRequest
2 голосов
/ 03 апреля 2020

Образцы документов:

{"_id": <id>, "name" : "Bread_1", "version" : 1 }
{"_id": <id>, "name" : "Bread_2", "version" : 1 }
{"_id": <id>, "name" : "Bread_1", "version" : 2 }
{"_id": <id>, "name" : "Bread_2", "version" : 2 }
{"_id": <id>, "name" : "Bread_3", "version" : 1 }

Требуемый вывод:

{"_id": <id>, "name" : "Bread_1", "version" : 2 }
{"_id": <id>, "name" : "Bread_2", "version" : 2 }
{"_id": <id>, "name" : "Bread_3", "version" : 1 }

Это вид группировки по имени и самой большой версии. Я пробовал этот запрос:

db.products.aggregate({$group: {_id: {name: '$name'}, version: {$max: '$version'}}});

Фактический вывод:

{"_id": {"name" : "Bread_1"}, "version" : 2 }
{"_id": {"name" : "Bread_2"}, "version" : 2 }
{"_id": {"name" : "Bread_3"}, "version" : 1 }

Хотя мне также нужен идентификатор документа. Что я пропустил в этом случае? Спасибо

1 Ответ

1 голос
/ 03 апреля 2020

Прямого способа получить его нет, поэтому вы можете попробовать запрос ниже:

db.products.aggregate([
  /** Group on 'name' & get max of 'version' & push all docs to 'docs' array field */
  {
    $group: {
      _id: "$name",
      version: { $max: "$version" },
      docs: { $push: "$$ROOT" }
    }
  },
  /** Transform fields in required format, Iterate over docs array & get '_id' of doc where version do match */
  {
    $project: {
      name: "$_id",
      version: 1,
      _id: {
        $let: {
          vars: {
            id: {
              $arrayElemAt: [ // As filter returns an array get first doc, There can only be one doc
                {
                  $filter: {
                    input: "$docs",
                    cond: { $eq: ["$$this.version", "$version"] } // Check max version == current object's version
                  }
                },
                0
              ]
            }
          },
          in: "$$id._id"
        }
      }
    }
  }
]);

Тест: MongoDB-Playground

...