Поиск вложенных массивов Mongodb

Пример структуры документа:

{ "dob": "12-13-2001", "name": "Kam", "visits": { "0": { "service_date": "12-5-2011", "payment": "40", "chk_number": "1234455", }, "1": { "service_date": "12-15-2011", "payment": "45", "chk_number": "3461234", }, "2": { "service_date": "12-25-2011", "payment": "25", "chk_number": "9821234", } } } { "dob": "10-01-1998", "name": "Sam", "visits": { "0": { "service_date": "12-5-2011", "payment": "30", "chk_number": "86786464", }, "1": { "service_date": "12-15-2011", "payment": "35", "chk_number": "45643461234", }, "2": { "service_date": "12-25-2011", "payment": "20", "chk_number": "4569821234", } } } 

В PHP я хочу перечислить все эти «посещения» информации (и соответствующее «имя»), для которых платеж меньше «30».

Я хочу печатать только визиты с «оплатой» <«30», а не другими. Является ли такой запрос возможным, или мне нужно сначала получить весь документ с помощью поиска, а затем использовать PHP для выбора таких посещений?

В документе примера значения «оплата» указаны как строки, которые могут не работать так, как предполагалось, с помощью команды $ lt. Для этого ответа я преобразовал их в целые числа.

Подстановочные запросы невозможны с MongoDB, поэтому с данной структурой документа ключ (0,1,2 и т. Д.) Поддокумента должен быть известен. Например, следующий запрос будет работать:

 > db.test.find({"visits.2.payment":{$lt:35}}) 

Однако,

 > db.test.find({"visits.payment":{$lt:35}}) 

В этом случае работать не будет, и

 > db.test.find({"visits.*.payment":{$lt:35}}) 

также не вернет никаких результатов.

Чтобы иметь возможность запрашивать встроенные документы «посещения», вы должны изменить структуру своего документа и сделать «посещения» в массиве или вложенных документах, например:

 > db.test2.find().pretty() { "_id" : ObjectId("4f16199d3563af4cb141c547"), "dob" : "10-01-1998", "name" : "Sam", "visits" : [ { "service_date" : "12-5-2011", "payment" : 30, "chk_number" : "86786464" }, { "service_date" : "12-15-2011", "payment" : 35, "chk_number" : "45643461234" }, { "service_date" : "12-25-2011", "payment" : 20, "chk_number" : "4569821234" } ] } 

Теперь вы можете запросить все встроенные документы в «посещениях»:

 > db.test2.find({"visits.payment":{$lt:35}}) 

Для получения дополнительной информации, пожалуйста, обратитесь к документации Mongo в виде точечной нотации:

http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

Теперь на вторую часть вашего вопроса: невозможно вернуть только условный поднабор встроенных документов.

В любом формате документа невозможно вернуть документ, содержащий ТОЛЬКО поддокументы, соответствующие запросу. Если один из поддокументов соответствует запросу, то весь документ соответствует запросу, и он будет возвращен.

Согласно Монгольскому документу «Получение подмножества полей»

http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields

Мы можем вернуть части встроенных документов следующим образом:

 > db.test2.find({"visits.payment":{$lt:35}},{"visits.service_date":1}).pretty() { "_id" : ObjectId("4f16199d3563af4cb141c547"), "visits" : [ { "service_date" : "12-5-2011" }, { "service_date" : "12-15-2011" }, { "service_date" : "12-25-2011" } ] } 

Но мы не можем иметь условный поиск некоторых поддокументов. Самое близкое, что мы можем получить, это оператор $ slice, но это не условно, и вам нужно будет сначала узнать расположение каждого поддокумента в массиве:

http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-RetrievingaSubrangeofArrayElements

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

Вы можете попробовать:

 $results = $mongodb->find(array("visits.payment" => array('$lt' => 30))); 

Но я не знаю, будет ли это работать, поскольку visits – это объект. BTW, судя по тому, что вы разместили, может быть перенесено в массив (или должно, поскольку числовые имена свойств имеют тенденцию вызывать путаницу)

try – db.test2.find ({"visit.payment": "35"})