2012-06-04 7 views
0

У меня есть модель, которая содержит массив встроенных документов. Эти встроенные документы отслеживают точки, которые пользователь заработал в данном действии. Поскольку пользователь может быть частью нескольких действий или только одного, имеет смысл сохранить эти действия в массиве. Теперь я хочу извлечь зал славы, десятку пользователей для данной деятельности. В настоящее время я делаю это так:Mongoose: вернуть только один встроенный документ из массива встроенных документов

userModel.find({ "stats.activity": "soccer" }, ["stats", "email"]) 
.desc("stats.points") 
.limit(10) 
.run (err, users) -> 

(если вы хотите знать о синтаксисе, это CoffeeScript)

где «статистика» является массив вложенных документов/activeties.

Теперь это действительно работает, но в настоящее время я тестирую только учетные записи, у которых есть только одно действие. Я предполагаю, что что-то пойдет не так (сортировка), как только пользователь будет иметь больше действий. Есть ли в любом случае я могу сказать мангусте только вернуть встроенный документ, где «активность» == «футбол» наряду с документом верхнего уровня?

Btw, я понимаю, что могу сделать это по-другому, имея статистику в своей собственной коллекции и имея db-ref соответствующему пользователю, но мне интересно, возможно ли это сделать так, прежде чем я рассмотрю любые переписывает.

Спасибо!

ответ

1

Вы правы, что это не сработает, если у вас есть несколько действий в вашем массиве.

В частности, поскольку вы не можете вернуть только произвольное подмножество массива с элементом, вы вернете все его, и сортировка будет применяться во всех точках, а не только к тем, которые «спарены» с «активностью» ":"футбольный".

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

{ _id: userId, 
    email: email, 
    stats: [ 
    {soccer : points}, 
    {rugby: points}, 
    {dance: points} 
    ] 
} 

Теперь вы сможете запросить и сортировать так:

users.find({"stats.soccer":{$gt:0}}).sort({"stats.soccer":-1}) 

Обратите внимание, что при переходе к версии 2.2 (в настоящее время доступна только в нестабильной разрабатываемой версии 2.1) вы бы иметь возможность использовать aggregation framework, чтобы получить точные результаты, которые вы хотите (только конкретное подмножество массива или поддокумент, соответствующий вашему запросу) без изменения вашей схемы.

+0

+1 для обходного пути. –

+0

Есть ли способ имитировать это без явного определения каждого действия? Как есть, вам не нужно было бы изменять схему, если бы вы хотели, например, добавить «бейсбольную» активность? –

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