Монгодская точка обозначение wildcard?
У меня есть коллекция пользователей, каждая из которых может быть подписана на одну или несколько служб. Каждая служба имеет некоторые метаданные, включая количество кредитов, которые пользователь имеет для этой услуги.
Как я могу найти все пользовательские объекты, которые имеют менее 50 кредитов для какой-либо службы, если у меня нет способа узнать, какие ключи объектов службы будут?
Понятно, что это будет что-то вроде этого, что не работает:
db.users.find({services.*.credits : {$lt : 50}})
Коллекция пользователей:
{
_id: 4f0ea25072139e4d2000001f,
services : {
a : { credits : 100, score : 2000 },
b : { credits : 200, score : 300 },
c : { credits : 10, score : 1300 }
}
},
{
_id: 4f0ea25072139e4d2000001f,
services : {
f : { credits : 68, score : 14 },
q : { credits : 1000, score : 102 },
z : { credits : 59, score : 352 }
}
}
Здесь объясняется другой пример того, что я хочу сделать, если это неясно здесь: http://www.mongodb.org/display/DOCS/Advanced+Queries#comment-346075854
Ответы
Ответ 1
Я думаю, было бы проще, если бы вы поместили этот объект службы в массив, так что вы можете использовать $elemMatch
, например:
{
services : [
{key: "a" , credits : 100, score : 2000 },
{key: "b", credits : 200, score : 300 },
{key: "c", credits : 10, score : 1300 }
]
}
и
{
_id: 4f0ea25072139e4d2000001f,
services : [
{key: "f", credits : 68, score : 14 },
{key: "q", credits : 1000, score : 102 },
{key: "z", credits : 59, score : 352 }
]
}
Тогда запрос, который вы напишете, будет таким:
db.coll.find({services: {$elemMatch : {credits: {$lt: 50}}}});
результат:
{ "_id" : ObjectId("4f0f2be07561bf94ea47eec4"), "services" : [ { "key" : "a", "credits" : 100, "score" : 2000 }, { "key" : "b", "credits" : 200, "score" : 300 }, { "key" : "c", "credits" : 10, "score" : 1300 } ] }
Ответ 2
Это реальный ответ на ваш вопрос.
Как вы можете найти все пользовательские объекты, которые имеют менее 50 кредитов для какой-либо службы, если у вас нет способа узнать, какие ключи объектов службы будут следующими:
Используйте запрос $where:
db.users.find({
$where: function () {
for (var index in this.services)
if (this.services[index].credits < 50)
return this;
}
});
Ответ 3
Я не знаю, как это сделать, используя используемую схему. Мне кажется, вы злоупотребляете объектами как массивы. Если services
- массив (множественные подсказки, которые он должен быть), вы можете просто запросить
db.users.find({"services.credits" : { $lt : 50 }});
или используйте $elemMatch
, если вам нужно сопоставить несколько условий для одного элемента массива.