Как индексировать динамические атрибуты в MongoDB


8

У меня есть следующий вид данных (немного упрощенный из моего реального случая) в MongoDB:

{
    "name":"some name",
    "attrs":[
        {"n":"subject","v":"Some subject"},
        {"n":"description","v":"Some great description"},
        {"n":"comments","v":"Comments are here!"},
        ]
}

Массив attrs является контейнером для динамических атрибутов, т.е. я заранее не знаю, какие атрибуты там помещены. n обозначает имя, а v обозначает значение.

Книга MongoDB In Action описывает это как решение для использования динамических атрибутов в случае, когда атрибуты полностью предсказуемы. Это также описывает, что вы можете индексировать это так:

db.mycollection.ensureIndex({"attrs.n":1, "attrs.v":1})

Запросы могут быть выполнены следующим образом:

db.mycollection.find({attrs: {$elemMatch: {n: "subject", v: "Some subject"}}})

Когда я проверяю это, я получаю очень плохую производительность. Я протестировал с mycollection, имеющим 2 миллиона документов, и отсутствие индекса, кажется, работает лучше.

Итак, вопрос состоит в том, существует ли способ индексировать этот вид динамических атрибутов, чтобы индексирование давало хорошую производительность? В моем случае нецелесообразно просто иметь ключи типа «субъект» и «описание» и индексировать их все ...

Ответы:


5

Я также задал этот же вопрос (в несколько расширенной форме) в списке рассылки mongodb-user , где получил ответ. Читайте оттуда, чтобы получить более подробную информацию. Короткий ответ: стратегия, используемая в вопросе, должна работать нормально, но есть проблема, которая делает ее очень неэффективной. Надеюсь, проблема будет решена в ближайшее время.

В моем случае мне нужно только запросить точные совпадения для кортежа {n, v}, чтобы я мог создать индекс с несколькими ключами:

db.mycollection.ensureIndex({"attrs":1})

и заставить их запросить вот так:

db.mycollection.find({"attrs": {n: "subject", v: "Some subject"}})

который прекрасно работает и использует индекс очень эффективно.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.