MongoDB, PyMon go как отфильтровать результаты по количеству уникальных полей? - PullRequest
0 голосов
/ 03 апреля 2020

MongoDb содержит следующий набор данных

[{"user": "a", "domain": "some.com"},
{"user": "b", "domain": "some.com"},
{"user": "b1", "domain": "some.com"},
{"user": "c", "domain": "test.com"},
{"user": "d", "domain": "work.com"},
{"user": "aaa", "domain": "work.com"},
{"user": "some user", "domain": "work.com"} ] 

Мне нужно выбрать первые элементы, отфильтрованные по домену, не более 2 одинаковых доменов в результате. После mon go результат запроса должен выглядеть следующим образом:

[{"user": "a", "domain": "some.com"},
{"user": "b", "domain": "some.com"},
{"user": "c", "domain": "test.com"},
{"user": "d", "domain": "work.com"},
{"user": "aaa", "domain": "work.com"}]

Всего 2 результата с одним доменом, остальные с теми же доменами должны быть пропущены. Возможно ли это сделать с $ aggregation, $ filter или чем-то еще?

Можно ли группировать по доменам и получать только первые N (2 в примере) пользовательских данных? Пример:

[{"domain": "some.com", "users": [a, b]}]

, поэтому

{"user": "b1", "domain": "some.com"} will be skip

1 Ответ

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

Вы можете получить желаемый результат при агрегировании MongoDB.

Он состоит из четырех этапов: 1. Группируем по полю domain и накапливаем в data документы с одинаковым доменным именем 2. Затем мы склеиваем массив, чтобы установить максимум 2 элемента на домен 3. Сглаживаем поле data с оператором $unwind 4. Возвращаем исходную структуру документа с оператором $replaceRoot

db.collection.aggregate([
  {
    "$group": {
      "_id": "$domain",
      "data": { "$push": "$$ROOT" }
    }
  },
  {
    "$addFields": {
     "data": {
        "$slice": [ "$data", 0, 2 ]
      }
    }
  },
  {
    "$unwind": "$data"
  },
  {
    $replaceRoot: { "newRoot": "$data" }
  }
])

MongoPlayground | Pymon go Агрегация

...