2012-06-28 1 views
3

Существует структура моих документов MongoDB:Как получить определенный объект из массива объектов внутри конкретного документа MongoDB?

{ 
    _id : "12345", 
    name : "foo", 
    object : { 
     array_of_objects : [{ 
      id : 507, 
      name : "some name", 
      dt : "2012-06-27 16:35:50" 
     },{ 
      id : 506 
      name : "some other name", 
      dt : "2012-06-21 16:09:05" 
     }, 
     … 
     ] 
    } 
} 

Мне нужно получить объект из array_of_objects с определенным идентификатором документа с указанным именем . Я использую PHP и попытался выполнить следующий код:

$collection->find(array('name' => 'foo', 'object.array_of_objects.id' => 507)); 

Он возвращает все элементы array_of_objects вместо элемента с идентификатором 507. После этого я пытаюсь сделать запрос с $ elemMatch:

$collection->find(array('name' => 'foo', 'object.array_of_objects' => array('$elemMatch' => array('id' => 507)))); 

Но оно было возвращено то же самое. :( My MongoDB version 2.0.6. Пожалуйста, помогите.

+0

Минус из MongoDB: http://stackoverflow.com/questions/10042097/how-to-search-data-in-inner-array-in-mongodb –

+0

@ Дэвид-Cheung спасибо! Итак, я постараюсь сделать это с помощью Mapreduce. – bibimij

ответ

3

Эта проблема была решена, и будет доступен в MongoDB версии 2.2, следующий стабильный релиз: https://jira.mongodb.org/browse/SERVER-828

Я просто попробовал его с помощью MongoDB 2.1.2 (нестабильный, разработка нт релиз):

образец документ:

{ "_id" : 1, "object" : { "array" : [ { "id" : 507, "name" : "Jenna" }, { "id" : 506, "name" : "Matt" } ] } } 

запрос:

db.food.find({_id:1, "object.array.id":506},{_id:0, "object.array.$":1}) 

результат:

{ "object" : { "array" : [ { "id" : 506, "name" : "Matt" } ] } } 
+1

Хорошая новость! 8) Спасибо, @ Jenna! – bibimij

+0

К сожалению, я использую http://mongohq.com, поэтому я не могу обновить MongoDB. :( – bibimij

0

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

Теперь драйвер PHP может сделать больше работы, я не знаю. - Я говорю о ключевых запросов MongoDB

+0

Вы можете вернуть подмножество полей - проверить документацию MongoDB: http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields – Jenna

+0

@ Jenna да, вы правы - но определенный элемент из массива на основе его значения? – Blacksad

+0

Как я понимаю, это можно сделать либо путем получения всего массива объектов, либо поиска нужного элемента с помощью PHP, либо с помощью MapReduce, правильно? – bibimij

0

Итак, я сделал это с MapReduce. Надеюсь, это сэкономит время и нервы.

$name = 'foo'; 
$id = 507; 

$mongo = new Mongo('…'); 

$db = $mongo->my_db; 

$map = new MongoCode('function(){'. 
    'this.object.array_of_objects.forEach(function(obj){'. 
     'if (obj.id == '.$id.')'. 
      'emit(1, obj);'. 
    '});}' 
); 

$reduce = new MongoCode('function(k,v){ return [k,v]; }'); 

$response = $db->command(array(
    'mapreduce' => 'my_collection', 
    'map' => $map, 
    'reduce' => $reduce, 
    'query' => array('name' => $name), 
    'out' => array('inline' => 1) 
)); 

var_dump($response['result']); 
Смежные вопросы