Как мне отобразить минимальное / максимальное значение вместе с соответствующим уникальным идентификатором в MongoDB?

mongodb #aggregation-framework

#mongodb #структура агрегации

Вопрос:

3 документа из моей коллекции выглядят так, как показано ниже.

 {'r1': {'t1': 600,
        't2': 300,
        'efficiency': 67},
 'r2': {'t1': 800,
        't2': 400,
        'efficiency': 71},
 'userId': ObjectId('5fedca01bbd56000131faaaa')},
{'r1': {'t1': 700,
        't2': 640,
        'efficiency': 60},
 'r2': {'t1': 200,
        't2': 150,
        'efficiency': 70},
 'userId': ObjectId('5fedca01bbd56000131fbbbb')},
{'r1': {'t1': 900,
        't2': 400,
        'efficiency': 75},
 'r2': {'t1': 820,
        't2': 380,
        'efficiency': 80},
 'userId': ObjectId('5fedca01bbd56000131fcccc')}
 

Я намереваюсь получить минимальное значение уникальный идентификатор пользователя для всех полей, кроме efficiency, где мне нужно максимальное значение уникальный идентификатор пользователя. Итак, я намереваюсь добиться чего-то вроде приведенного ниже:

 {
  'userId': ObjectId('5fedca01bbd56000131faaaa'), 'r1t1': 600
  'userId': ObjectId('5fedca01bbd56000131faaaa'), 'r1t2': 300
  'userId': ObjectId('5fedca01bbd56000131fbbbb'), 'r2t1': 200
  'userId': ObjectId('5fedca01bbd56000131fbbbb'), 'r2t2': 150
  'userId': ObjectId('5fedca01bbd56000131fcccc'), 'r1eff': 75
  'userId': ObjectId('5fedca01bbd56000131fcccc'), 'r2eff': 80
}
 

Мне удалось получить минимальные / максимальные значения с помощью приведенного ниже кода. Однако, как мне объединить эти значения с соответствующим идентификатором пользователя?

 group1 = {
    "$group": {
        "_id": {},
        "r1t1": {"$min": "$r1.t1"},
        "r1t2": {"$min": "$r1.t2"},
        "r2t1": {"$min": "$r2.t1"},
        "r2t2": {"$min": "$r2.t2"},
        "r1eff": {"$max": "$r1.efficiency"},
        "r2eff": {"$max": "$r2.efficiency"},
    }
}
 

Если я добавлю «_id»: «$ userId», я получу вывод только с 1 идентификатором пользователя, но я надеялся на 6 уникальных идентификаторов пользователя.

Что мне нужно добавить для получения правильного вывода? Заранее благодарю вас!

Комментарии:

1. Изменить "_id": {}, на "_id": "$_id", . Также ваш ожидаемый результат не является допустимым выводом. Каждая строка в вашем ожидаемом выводе должна выглядеть так [ { "userId": ObjectId(...), 'r1t1': 600, etc }, { "userId: ..., 'prop': val } ]

Ответ №1:

Запрос

  • mongodb также может сортировать документы (по полям один за другим в порядке их появления), этот способ используется здесь для сохранения пользователя, у которого есть это минимальное / максимальное значение

PlayMongo

 aggregate(
[{"$group": 
    {"_id": null,
      "r1t1": {"$min": {"min": "$r1.t1", "userId": "$userId"}},
      "r1t2": {"$min": {"min": "$r1.t2", "userId": "$userId"}},
      "r2t1": {"$min": {"min": "$r2.t1", "userId": "$userId"}},
      "r2t2": {"$min": {"min": "$r2.t2", "userId": "$userId"}},
      "r1eff": {"$max": {"max": "$r1.efficiency", "userId": "$userId"}},
      "r2eff": {"$max": {"max": "$r2.efficiency", "userId": "$userId"}}}},
  {"$unset": ["_id"]}])
 

Результаты

  • результаты почти такие же, как вы хотели, если вам нужно именно то, что вы просили, его можно изменить
 [{
  "r1t1": {
    "min": 600,
    "userId": ObjectId("5fedca01bbd56000131faaaa")
  },
  "r1t2": {
    "min": 300,
    "userId": ObjectId("5fedca01bbd56000131faaaa")
  },
  "r2t1": {
    "min": 200,
    "userId": ObjectId("5fedca01bbd56000131fbbbb")
  },
  "r2t2": {
    "min": 150,
    "userId": ObjectId("5fedca01bbd56000131fbbbb")
  },
  "r1eff": {
    "max": 75,
    "userId": ObjectId("5fedca01bbd56000131fcccc")
  },
  "r2eff": {
    "max": 80,
    "userId": ObjectId("5fedca01bbd56000131fcccc")
  }
}]
 

Комментарии:

1. Этот ответ был именно тем, на что я надеялся! И мне нравится ваш подход к оператору «unset», который сделал результаты более красивыми. Вы сделали мой день. Спасибо!

2. хорошо, mongodb сравнивает документы, также см. Это