Агрегируйте всю коллекцию, находите повторяющиеся элементы между массивами — затем распечатайте массив/json

#mongodb #mongodb-query

Вопрос:

Я пытаюсь понять, как объединить все документы внутри Коллекции.

Каждый документ имеет массив IP — адресов-как бы я продолжил агрегировать каждый документ и посмотреть, был ли найден какой-либо IP-адрес в 1 документе в другом?

Таким образом, он в основном просто просматривает каждый массив в каждом документе, а затем распечатывает идентификатор, найденный с помощью IP-адресов, а затем IP-адреса. < Пример на рисунке ниже

Я попытался выполнить несколько агрегаций, но, поскольку это массив, я мог сделать так, чтобы он отображался в основном только в том случае, если полный массив был идентичен массиву в другом документе, что означает, что, хотя 2 IP — адреса из 3 будут найдены в другом документе, он не будет печататься-потому что он не был идентичен полному массиву.

Я знаю, что это может быть «проблемой скорости» в долгосрочной перспективе со многими документами, но пока оставим это.

введите описание изображения здесь

Мои пожелания: Распечатайте идентификатор вместе с IP-адресом, который был найден в другом документе

только если он напечатан, если найдено 2 или более.

Как бы я получил распечатку этого — вроде как в примере ниже: (IP, который был найден в нескольких массивах документов — и какой идентификатор был в этом документе)

 { 
  "82.102.20.247": [
     "113616977779621895", 
     "11361612412495"
   ],

  "12.435.45.20": [
     "113616977124364587", 
     "113616977779621895"
   ],
  ...
}
 

Ответ №1:

  • $project для отображения обязательных полей
  • $unwind деконструировать ip массив
  • $group по ip и постройте id массив, получите общее количество
  • $match чтобы проверить, что общее count количество больше или равно 2
  • $group по null и постройте значение ключа с ip помощью и ids
  • $arrayToObject преобразуйте выше построенный массив в объект
  • $replaceRoot чтобы заменить указанный выше объект на корневой
 db.collection.aggregate([
  {
    $project: {
      _id: 0,
      id: 1,
      ip: 1
    }
  },
  { $unwind: "$ip" },
  {
    $group: {
      _id: "$ip",
      ids: { $push: "$id" },
      count: { $sum: 1 }
    }
  },
  { $match: { count: { $gte: 2 } } },
  {
    $group: {
      _id: null,
      ips: {
        $push: {
          k: "$_id",
          v: "$ids"
        }
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: { $arrayToObject: "$ips" }
    }
  }
])
 

Игровая площадка

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

1. Большое вам спасибо! Сначала вернусь к компьютеру здесь через несколько часов для тестирования, просто быстро отвечу с телефона. Как насчет поиска IP-адресов только с 2 или более высокими результатами идентификации? Чтобы как бы избежать появления единственных? Я бы предположил, что это какой-то $gte: 2 .. кроме того, я понятия не имел о существовании этого веб-сайта, который очень помогает при тестировании, а не перезапуске проекта снова и снова для изменений!

2. я обновил ответ с учетом вашего условия соответствия.

3. С игровой площадки это выглядит намного лучше, чем мое первое желание продолжить — у меня были мысли о циклическом просмотре каждого документа без агрегата, чтобы в основном написать код, который делает то, что здесь делает агрегат, — и это гораздо более удобно для производительности! Большое вам спасибо за быстрый ответ, я не могу дождаться, чтобы попробовать его позже!