2015-07-25 1 views
1

У меня есть документы, подобные этому в коллекции x в MongoDB:запросов для документов, которые имеют внутренний суб-поле при заданном значении

{ 
    "_id" : ... 
    "attrKeys": [ "A1", "A2" ], 
    "attrs" : { 
     "A1" : { 
      "type" : "T1", 
      "value" : "13" 
     }, 
     "A2" : { 
      "type" : "T2", 
      "value" : "14" 
     } 
    } 
} 

A1 и A2 элементы Выше приведены лишь Примеры: attrs поля могут удерживайте любое количество ключей любого имени. Имена ключей в attrs хранятся в поле attrNames.

Я хотел бы запросить документы, имеющие attr с подполем заданного значения. Например, запрос для документов, которые имеют элемент в ключевой карте attr, подполем type является «T4». Что-то вроде этого:

db.x.find({"attrs.$any.type": "T4"}) 

(avobe не юридический язык MongoDB запрос, но я думаю, что это может помочь, чтобы получить представление).

Этот вопрос возможен с MongoDB? Существует ли какое-либо обходное решение в случае, если MongoDB не поддерживает этот запрос? Благодаря!

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

Я имею в виду, что с помощью карты ключей два независимых клиента могут изменять элементы attrs, поскольку один клиент может делать db.x.update({_id: "y"}, {$set: { "attrs.A1.value": "12" } }, а другой клиент делает db.x.update({_id: "y"}, {$set: { "attrs.A2.value": "55" } }, не вмешиваясь друг в друга.

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

+0

Относительно «Любой намек на то, как [параллельный доступ с использованием массивов] может быть выполнен?» Я могу задать отдельный вопрос, если сообщество лучше подумает. – fgalan

+0

Как вы считаете, проблема с одновременным доступом здесь? объясните, почему вы думаете, что массив вызывает проблемы. –

+0

У меня есть проблема в отдельном вопросе http://stackoverflow.com/questions/31643054/concurrent-update-of-array-elements-which-are-embedded-documents-in-mongodb. Спасибо за вашу помощь! – fgalan

ответ

1

Это всегда было возможно с MongoDB, потому что всегда была возможность contruct условий запроса с использованием JavaScript evaluation:

db.attrs.find(function() { 
    var attrs = this.attrs; 
    return Object.keys(attrs).some(function(key) { 
     return attrs[key].value === "14" 
    }); 
}) 

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

Но это не вопрос о «возможном», но более один из «это действительно хорошая идея», для которого основным ответом является «Нет».

Базы данных - это переменчивые звери, которые хотят оптимизировать такие вещи, как индексы и т. Д., А также их собственный ожидаемый оператор, чтобы сделать поиск максимально эффективным. Так что да, вы можете пройти через переводчик языка, который эффективно грубой силой оценивает закодированное условие для каждого документа, или вы можете пересмотреть свой шаблон дизайна.

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

{ 
    "attrs" : [ 
     { "key": "A1", "type" : "T1", "value" : "13" }, 
     { "key": "A2", "type" : "T2", "value" : "14" } 
    ] 
} 

Организованный таким образом запрос становится таким же простым, как:

db.attrs.find({ "attrs.value": "14" }) 

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

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

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

+0

Спасибо за столь подробный ответ! Как вы объясните, использование массива для 'attrs' может сделать запрос намного проще, но есть причины не использовать массив в моем приложении (я отредактировал исходный вопрос, чтобы уточнить его). – fgalan

+0

Связанный с этим, я нашел на http://stackoverflow.com/questions/9200399/replacing-embedded-document-in-array-in-mongodb, что «по моему опыту массив шаблонов объектов не является оптимальным, если объекты имеют естественный идентификатор »(в этом случае естественный идентификатор является« ключом »attr, например A1, A2 и т. д.). – fgalan

Смежные вопросы