Объединение регулярных выражений и вложенных объектов в запросах mongodb
Я пытаюсь объединить запросы регулярных выражений и встроенных объектов и терпит неудачу. Я либо беру ограничение mongodb, либо просто получаю что-то немного не так, может, кто-то из них сталкивался с этим. Документация, конечно, не охватывает этот случай.
запрашиваемые данные:
{
"_id" : ObjectId("4f94fe633004c1ef4d892314"),
"productname" : "lightbulb",
"availability" : [
{
"country" : "USA",
"storeCode" : "abc-1234"
},
{
"country" : "USA",
"storeCode" : "xzy-6784"
},
{
"country" : "USA",
"storeCode" : "abc-3454"
},
{
"country" : "CANADA",
"storeCode" : "abc-6845"
}
]
}
Предположим, что коллекция содержит только одну запись
Этот запрос возвращает 1:
db.testCol.find({"availability":{"country" : "USA","storeCode":"xzy-6784"}}).count();
Этот запрос возвращает 1:
db.testCol.find({"availability.storeCode":/.*/}).count();
Но этот запрос возвращает 0:
db.testCol.find({"availability":{"country" : "USA","storeCode":/.*/}}).count();
Кто-нибудь понимает почему? Это ошибка?
Спасибо
1 ответ
Вы неправильно ссылаетесь на встроенный код магазина - вы ссылаетесь на него как на встроенный объект, когда на самом деле у вас есть массив объектов. Сравните эти результаты:
db.testCol.find({"availability.0.storeCode":/x/});
db.testCol.find({"availability.0.storeCode":/a/});
Используя приведенный выше пример документа, первый не вернется, потому что первый storeCode не содержит х ("abc-1234"), второй вернет документ. Это хорошо для случая, когда вы смотрите на один элемент массива и проходите в позиции. Чтобы найти все объекты в массиве, вам нужно $ elemMatch
В качестве примера я добавил этот второй пример документа:
{
"_id" : ObjectId("4f94fe633004c1ef4d892315"),
"productname" : "hammer",
"availability" : [
{
"country" : "USA",
"storeCode" : "abc-1234"
},
]
}
Теперь посмотрим на результаты этих запросов:
PRIMARY> db.testCol.find({"availability" : {$elemMatch : {"storeCode":/a/}}}).count();
2
PRIMARY> db.testCol.find({"availability" : {$elemMatch : {"storeCode":/x/}}}).count();
1