MongoDB: используйте $ позиционный оператор для запросов - PullRequest
6 голосов
/ 08 июня 2011

У меня есть коллекция с записями, которые выглядят так:

{
    "userid": 1, 
    "contents": [ 
            { "tag": "whatever", "value": 100 }, 
            {"tag": "whatever2", "value": 110 } 
    ] 
}

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

Вот более точно, что я хотел бы сделать:

collection.find({'contents.tag':"whatever"},{'contents.$.value':1})

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

Вы знаете, что не так? Я думал, что, возможно, оператор $ можно использовать только для обновления, а не для запросов. Кто-нибудь в курсе?

Спасибо!

Ответы [ 4 ]

8 голосов
/ 24 июня 2012

Вам нужен оператор $ elemMatch .

8 голосов
/ 08 июня 2011

Да, вы правы - позиционный оператор используется для обновления объекта.

На данный момент решение состоит в том, чтобы вернуть массив и извлечь поле в вашем приложении.

Существует открытый запрос улучшения для этой функции (в запросах):

https://jira.mongodb.org/browse/SERVER-828

Для получения дополнительной информации о позиционном операторе см .:

http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

0 голосов
/ 24 июля 2013

Создайте запрос с $ in вместо этого и добавьте равное значение в массив, это может решить вашу проблему

$users_array = array(xxxxxxxx,yyyyyy);     
$user = Db::find('fb_users', array(
                            'facebook_id' => array(
                                '$in' => array($users_array)
                            )
                        ));
0 голосов
/ 23 августа 2011

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

сначала, предварительно отфильтруйте запрос, сгенерируйте все элементы массива на карте, отфильтруйте те, которые не совпадают ни в emit, ни в lower.Если вы не укажете, все будет происходить в ОЗУ.

Если вам приходится часто выполнять такие запросы, возможно, стоит скопировать данные.

Тем не менее, я надеюсь, что сервер SERVER-828 будет скоро внедрен!

...