PHP и Mongo: поиск вложенных документов с пользовательским идентификатором

Я создал коллекцию «params» в Mongo со следующей структурой:

{
    "_id" : "id1",
    "list" : [
        {
            "type" : "type1",
            "subtypes" : [ "id1 subtype11", "id1 subtype12" ]
        }
        {
            "type" : "type2",
            "subtypes" : [ "id1 subtype21", "id1 subtype22" ]
        }
    ]
}
{
    "_id" : "id2",
    "list" : [
        {
            "type" : "type1",
            "subtypes" : [ "id2 subtype11", "id2 subtype12" ]
        }
        {
            "type" : "type2",
            "subtypes" : [ "id2 subtype21", "id2 subtype22" ]
        }
    ]
}

Я хочу получить все "subtypes" для "_id":"id1" и "type":"type1". Я узнал, что способ сделать это в оболочке Mongo

db.params.find (
    { $and: [
        {"_id" : "id1"},
        {"list.type" : "type1"}
    ] }
)

У меня есть два вопроса:

  1. Правильно ли я использую $and (читай: «я создаю запрос»)?
  2. Как правильно разобрать этот запрос на PHP-код? Я теряюсь в синтаксисе :(.

Благодарю вас!


person jfabian    schedule 13.06.2013    source источник
comment
1. Нет, можно убрать $ и он не нужен, 2. Что ты имеешь в виду?   -  person Sammaye    schedule 13.06.2013
comment
Спасибо за подсказку, хотя вторую запись я тоже не получу, так как она тоже имеет элемент "type":"type1" в массиве "list"? Кроме того, я понял, что я должен сначала получить полную запись для `_id:id1, прежде чем делать что-либо еще в моем PHP-коде, поэтому весь процесс должен стать проще. Спасибо!   -  person jfabian    schedule 13.06.2013
comment
Нет, вы бы не стали, это не оператор $or между свойствами объекта в запросе, а $and по умолчанию, а также явный оператор $and действует немного по-другому с индексами, поэтому лучше не использовать там никакого оператора.   -  person Sammaye    schedule 13.06.2013
comment
Ой! Извините, я не правильно понял, что вы написали, теперь понял. Кстати, еще один вопрос: что, если я хочу создать массив со значениями полей type, поэтому, если я хочу найти "_id":"id1", я получаю ["type1", "type2"]? Возможно ли это сделать (я предполагаю, что необходима структура агрегации)? Спасибо!   -  person jfabian    schedule 13.06.2013
comment
С вашей текущей структурой вам понадобится структура агрегации с использованием $unwind, однако, если честно, это, вероятно, лучше сделать на PHP.   -  person Sammaye    schedule 13.06.2013


Ответы (2)


Оказывается, PHP-код, отвечающий на этот вопрос, на самом деле не так уж и сложен:

$query = array('_id' => 'id1', 'list.type' => 'type1');
$result = $collection->find($query);

/* Use this to access each element of the results */
foreach($result as $doc) {
    /* Code goes here */
}

Если кто-то хочет вместо этого использовать каждое значение в "type" (и, например, распечатать их все), код будет таким:

$output = [];
$query = array('_id' => 'id1');
$field = array('list.type' => true);

$result = $collection->find($query, $field);
foreach($result as $doc) {
    foreach($doc['list'] as $elem) {
        $output[] = $elem['type'];
    }
}

Я узнал все это, используя функцию var_dump() для каждого документа и анализируя вывод. Надеюсь, это поможет таким новичкам, как я. Спасибо Sammaye за советы! :)

person jfabian    schedule 14.06.2013

$Коллекция->найти(массив(), массив('USERS.TASKS.MISSION_SAS_ID' => true));

используйте этот код выше, чтобы получить данные поддокумента

person Shiv Kumar Sah    schedule 25.10.2013