Сортировать по динамически добавленному полю - PullRequest
0 голосов
/ 11 февраля 2019

У меня в базе данных 20 миллионов документов следующим образом.

 {
    "_id": ObjectId("5bb84e931cb3d25a3b21d14e"),
    "merchant": "menswearhouse.com",
    "category": "Fashion > Clothing > Men's Clothing",
    "feature": [
      "-0.899652959529",
      "-0.02401520125567913",
      "0.08394625037908554",
      "0.06319021433591843",
      "-0.015963224694132805"
    ]
  }

Теперь у меня есть массив ниже, с которым мне нужно найти документы.

const dummy = [
  "-0.899652959529",
  "-0.02401520125567913",
  "0.08394625037908554",
  "0.06319021433591843",
  "-0.015963224694132805"
];

Мне нужно

  1. Найти разность всех значений, т.е. необходимо вычесть первый индекс feature с первым индексом моего фиктивного массива и так далее для всех 5 значений.
  2. Взять квадратвсех значений
  3. Добавьте все 5 значений
  4. Возьмите квадратный корень.
  5. Сортируйте все значения с этим полем и получите только 5 документов.

Я использую этот запрос, который $project s поле, когда я использую $limit.Но мне нужно $sort с полем $project ed и мне нужно взять 5 лучших документов.Но есть 20 миллионов документов, которые ничего не возвращают и вечны.

db.collection.aggregate([
  { $project: {
    field: {
      $sqrt: {
        $sum: {
          $map: {
            input: { $range: [0, { $size: '$feature' }] },
            as: "d",
            in: {
              $pow: [
                {
                  $subtract: [
                    { $toDouble: { $arrayElemAt: [dummy, "$$d"] }},
                    { $toDouble: { $arrayElemAt: ["$feature", "$$d"] }}
                  ]
                },
                2
              ]
            }
          }
        }
      }
    }
  }}
])

Можно ли использовать индекс для поля, которое создается во время выполнения?

Спасибо !!!

1 Ответ

0 голосов
/ 01 марта 2019

Короткий ответ - нет.Вы не можете создать индекс для полей, созданных во время выполнения.На момент написания этой статьи MongoDB не может достичь того, чего вы хотите.Но вы можете рассчитать их параллельно.Предполагая, что ваш сервер имеет надлежащие ресурсы (процессор и память), вы можете в своем приложении разделить свои задания и выполнять их параллельно.Для простой математики предположим, что у вас есть 20 000 000 (мил) документов, и вы разделите их на 20 задач.Для каждой задачи она обработает 1 000 000 документов и выдаст 5 лучших результатов.Конвейер для первой задачи будет

[
    {
        '$sort': {
            '_id': 1
        }
    }, {
        '$skip': 0
    }, {
        '$limit': 1000000
    }, {
        '$project': {
            'field': {
                '$sqrt': {
                    <do your thing>
                }
            }
        }
    }, {
        '$limit': 5
    }
]

После того, как все потоки (задачи) вернутся, объедините результаты (только 100 документов) в вашем приложении, отсортируйте их по field и, наконец, получите ваши лучшие 5документы.Обратите внимание, что вы должны учитывать свои аппаратные ресурсы, чтобы найти оптимальное количество разделенных задач.

...