Каков оптимальный способ запроса MongoDB для документов, которые содержат определенное количество элементов c, содержащих определенную строку c? - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть база данных MongoDB, которая содержит документы в этом формате:

{
    "user": "username",
    "array": [
    {
        "field": "array element 1",
        "common":
        {
            "field to look for": "value to look for"
        }
    },
    {
        "field": "array element 2",
        "common":
        {
            "field to look for": "value to look for"
        }
    }
    {
        "field": "array element 3",
        "common":
        {
            "field to look for": "different value"
        }
    }]
}

Я ищу оптимальный (самый производительный и простой в создании) запрос, который возвращает массив документов, которые содержат указанные количество вхождений пары «поле для поиска: значение для поиска».

Кроме того, хотя и не требуется, было бы здорово, если бы запрос удовлетворял этим требованиям :

  • «Сумма» и «поле: значение» необходимо указывать только один раз (возможно, переменные или параметры операции запроса?)
  • «Сумма» должна указываться как «» "," больше "," меньше или равно "," между и "

Я привел примеры, в которых используется один и тот же набор документов:

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

Также обратите внимание, что хотя указанная мной структура документа, скорее всего, не оптимальна для таких запросов, она, скорее всего, останется прежней. Тем не менее, я был бы признателен за предложения по улучшению структуры документа.

В случае, если что-то случится со ссылками Mongoplayground, ниже приведены фрагменты с примером коллекции и мой запрос по первой ссылке.

Коллекция документов:

     {
            "user": "1 dis 2 vis",
            "creditCards": [
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              },
              {
                "common": {
                  "paymentMethodId": "VISA"
                }
              },
              {
                "common": {
                  "paymentMethodId": "VISA"
                }
              }
            ]
          },
          {
            "user": "3 dis",
            "creditCards": [
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              },
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              },
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              }
            ]
          },
          {
            "user": "2 dis 1 vis",
            "creditCards": [
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              },
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              },
              {
                "common": {
                  "paymentMethodId": "VISA"
                }
              }
            ]
          },
          {
            "user": "2 dis",
            "creditCards": [
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              },
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              }
            ]
          },
          {
            "user": "1 dis",
            "creditCards": [
              {
                "common": {
                  "paymentMethodId": "DISCOVER"
                }
              }
            ]
          },
          {
            "user": "1 vis",
            "creditCards": [
              {
                "common": {
                  "paymentMethodId": "VISA"
                }
              }
            ]
          }

Запрос, который я придумал:

db.collection.aggregate([
  {
    $match: {
      "creditCards.common.paymentMethod": "DISCOVER"
    }
  },
  {
    $group: {
      _id: "$creditCards.common.paymentMethod",
      doc: {
        $push: "$$ROOT"
      },
    }
  },
  {
    $unwind: "$_id"
  },
  {
    $match: {
      "_id": "DISCOVER"
    }
  },
  {
    $group: {
      _id: "$doc",
      "count": {
        "$sum": 1
      }
    }
  },
  {
    $match: {
      "count": {
        $gt: 1
      }
    }
  },
  {
    $project: {
      "count": false
    }
  }
])
...