Mongo DB: оптимизация запроса на основе уникального встроенного ключа - PullRequest
0 голосов
/ 20 декабря 2011

У меня есть коллекция Mongo, где у каждого документа есть набор уникальных встроенных ключей:

{
    Facebook :
    {
        Archived:'False' //non unique
        'fan_count_December_19_2011':12345, //unique
        'unique_views_count_December_19_2011':12345, //unique
        'post_count_December_19_2011':12345, //unique
        ...
        ...
    }
}

Мы ищем эти документы по следующему запросу:

db.metrics.find({
    {'Facebook.fan_count_December_19_2011' : {'$ne':null}},'Archived':'False'}
}
).limit(1)

Проблема в том, что с 6000 таких документов это немного медленно. Просмотр журнала Explain (); на выполнение каждого запроса в среднем уходит 0,06 секунды, и каждый раз выполняется полное сканирование коллекции. Наш сервис должен выполнить вышеуказанный запрос примерно 100 раз (для 100 различных ключей); что при 0,06 п / с добавляет до 6 секунд на вызов (не включая нагрузку на сайт, обслуживающий данные). Отправка всех ключей в одном пакете и выполнение одного большого запроса потребует серьезной перезаписи уровня данных; которого я пытаюсь избежать из-за приближающегося сжатого срока. Я просматривал документацию, и, похоже, нет способа получить индекс на основе ключа. В документации сказано, что вы можете индексировать встроенный ключ; но это, кажется, только индексировать значения. Это также не приносит мне большой пользы; поскольку каждый ключ в системе уникален; для каждого нового ключа должен быть индекс.

Если не пересматривать структуру нашего документа (что потребует серьезных изменений); Можно ли как-нибудь ускорить этот запрос к существующей коллекции в ее текущем формате?

Любой конструктивный вклад приветствуется.

Спасибо, Frank

Ответы [ 2 ]

1 голос
/ 20 декабря 2011

Предполагая, что вы установили для своего поля «Архив» значение true после обработки документа, вы можете создать индекс только для поля «Архив».

Обычно вы не создавали бы индекс для поля с низким количеством элементов, но в этом случае он мог бы работать для вас, но только при условии, что существует не очень много документов, в которых поле Архивные имеет значение false.

В долгосрочной перспективе вы должны изменить дизайн своего документа, чтобы у вас не было так много уникальных имен полей (что-то вроде предложения Iain о поле "Facebook.date"). Таким образом, у вас есть то, что вы можете создать индекс.

0 голосов
/ 20 декабря 2011

Это предположение, но я подозреваю, что оно выполняет сканирование диапазона из-за:

  1. Вы не указали индекс в поле или
  2. Вы выполняете фильтр не равных, который может не использовать индекс ... В документе Mongo говорится, что "операторы $ ne или $ nin MongoDB неэффективны с индексами."

Я предлагаю вам проиндексировать поле 'Facebook.fan_count_De December_19_2011' и использовать оператор больше чем.

db.metrics.find({
    {'Facebook.fan_count_December_19_2011' : {'$gte':1}},'Archived':'False'}
}
).limit(1)

Конечно, вам нужно будет создать множество индексов, но вы можете сделать это в расширенном сценарии без особых усилий.

Вы можете также рассмотреть вопрос о сохранении date в качестве поля, тогда вы можете сделать следующее:

db.metrics.find({
    {'Facebook.date' : {'$gte':'2011-12-01'}},'Archived':'False'}
}
).limit(100)

В любом случае вам нужен индекс, которого нельзя избежать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...