Создание индекса в Mongo

У меня есть набор данных в виде:

{
  u'geometry': {
    u'type': u'Point',
    u'coordinates': [157.0625, -24.36573]
  },
  u'_id': ObjectId('5ad70f71f2119236741ffad6'),
  u'type': u'Feature',
  u'properties': {
    u'STATUS': u'8',
    u'TIMESTAMP': u'2013-12-31 17:03:00.000',
    u'MMSI': u'636015036',
    u'SPEED': u'98'
  }
}

Я создаю запрос, который возвращает позиции (координаты) кораблей, сгруппированных по MMSI и отсортированных. Total: количество записей с одним и тем же MMSI, COORDINATES: координаты для одного и того же MMSI, собранные в массиве, и _id: MMSI судна.

Запрос (пимонго):

getPositionsOfshipsgrouped = db.samplecol.aggregate([
  { "$match": { "properties.MMSI": { "$exists": "true" } } },
  {
    "$project": {
      "properties.MMSI": "$properties.MMSI",
      "geometry.coordinates": "$geometry.coordinates"
    }
  },
  {
    "$group": {
      "_id": "$properties.MMSI",
      "total": { "$sum": 1 },
      "COORDINATES": { "$push": "$geometry.coordinates" }
    }
  },
  { "$match": { "total": { "$gte": 0 } } },
  { "$sort": { "total": -1 } },
  { "$limit": 15 }
])

Полученные результаты:

{
  u'total': 10,
  u'_id': u'503551000',
  u'COORDINATES': [
    [141.8705, -12.67311],
    [158.1707, -0.9142034],
    [157.1707, -0.9142034],
    [157.1707, -0.9142034],
    [157.1707, -0.9142034],
    [157.1707, -0.9142034],
    [159.1707, -0.8142034],
    [158.2707, -0.8142034],
    [159.1707, -0.8142034],
    [159.1707, -0.8142034]
  ]
}

{
  u'total': 2,
  u'_id': u'416243700',
  u'COORDINATES': [
    [159.1707, -0.8142034],
    [159.0707, -0.7142034]
  ]
}

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

db.samplecol.ensure_index([("geometry", "2dsphere")])

а затем я создаю индексы с одним ключом, например:

db.samplecol.ensure_index([
  ("properties.MMSI", 1),
  ("geometry.coordinates", 1),
  ("properties.TIMESTAMP", 1)
])

Я использую при создании индекса поля из $ project (в запросе выше).

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

К сожалению, ваш конвейер агрегации, о котором идет речь, не получит никакого повышения производительности от индексов. Есть ли причина, по которой вы используете $exists на первом этапе конвейера? Я спрашиваю, потому что избавление от этого и следующего $project фактически позволило бы нам перейти на $sort, и что "было бы" влияет на производительность. Так что в идеале ключ "properties.MMSI" должен быть в каждом документе.

Neil Lunn 23.04.2018 10:08

Нет, я могу избавиться от поля $ exists. Ключ "properties.MMSI" существует в каждом поле. Итак, без $ exists этот запрос с этими индексами повлияет на производительность?

e7lT2P 23.04.2018 10:10

Как часть этого, вероятно, одна из самых сложных вещей, с которой можно договориться, в отличие от чего-то вроде SQL, заключается в том, что $project в качестве «выбора» здесь действительно является "антипаттерн". $group фактически уже подразумевает, что поля, на которые он ссылается для вывода, фактически являются единственными обязательными полями документа. И оптимизатор запросов достаточно умен, чтобы понять, что *если вам не помешает.

Neil Lunn 23.04.2018 10:11

$exists действительно убивает его, как и $project. В идеале это был бы $sort,$group, а потом и все остальное. Но эти две комбинации в начале могут фактически выбирать и обрабатывать индекс. Как «покрытый», даже если у вас были оба свойства в одном индексе. Поэтому я бы оспорил, что вам это не нужно, а затем просто отбросил бы все результаты null из ключа группировки. Но без значений null он был бы намного более производительным. А может «частичные» индексы

Neil Lunn 23.04.2018 10:13

Я меняю свой запрос на следующий: getPositionsOfshipsgrouped = db.samplecol.aggregate ([{"$ group": {"_id": "$ properties.MMSI", "total": {"$ sum": 1}, "COORDINATES" : {"$ push": "$ geometry.coordinates"}}}, {"$ match": {"total": {"$ gte": 0}}}, {"$ sort": {"total": -1}}, {"$ project": {"properties.MMSI": "$ properties.MMSI", "geometry.coordinates": "$ geometry.coordinates"}}, {"$ limit": 15}]) . Я вижу небольшое сокращение времени с 0,0010 до 0,0008. Это ты имеешь в виду. Или мне нужно полностью удалить проекцию $?

e7lT2P 23.04.2018 10:25
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
62
0

Другие вопросы по теме