Поиск по вложенному массиву Mongodb - PullRequest
1 голос
/ 18 января 2012

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

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

Ответы [ 3 ]

18 голосов
/ 18 января 2012

В примере документа значения «payment» задаются в виде строк, которые могут не работать должным образом с помощью команды $ 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

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

1 голос
/ 18 января 2012

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

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

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

0 голосов
/ 21 марта 2016

try - db.test2.find ({"посещения.плата": "35"})

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