2012-01-17 8 views
1

документ структура пример: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 для выбора таких посещений?

ответ

18

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

Подстановочные запросы с 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}}) 

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

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" 
     } 
    ] 
} 

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

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

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

+0

Thankyou Marc для объяснения .. Думаю, мне придется использовать PHP для получения информации из полного документа. – pun

1

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

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

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

+0

Но это будет возвращать весь документ, содержащий "платеж" < "30", в том числе посещений, для которых «оплата «> 30. Спасибо за вашу помощь – pun

+0

Да, но не будут включать документы, у которых есть только оплата> 30, это лучшее, что вы можете сделать. –

0

попытка - db.test2.find ({ "visits.payment": "35"})

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