Пример структуры документа:
{ "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, но это не условно, и вам нужно будет сначала узнать расположение каждого поддокумента в массиве:
Для того чтобы приложение отображало только встроенные документы, соответствующие запросу, это необходимо сделать программным путем.
Вы можете попробовать:
$results = $mongodb->find(array("visits.payment" => array('$lt' => 30)));
Но я не знаю, будет ли это работать, поскольку visits
– это объект. BTW, судя по тому, что вы разместили, может быть перенесено в массив (или должно, поскольку числовые имена свойств имеют тенденцию вызывать путаницу)
try – db.test2.find ({"visit.payment": "35"})