开发者

Querying embedded documents on a document with MongoMapper

开发者 https://www.devze.com 2023-03-08 03:53 出处:网络
What is a good pattern for querying embedded documents on a document? For instance, my User document has an embedded Alerts document. If I want to see if a given User has an alert with name I can do i

What is a good pattern for querying embedded documents on a document? For instance, my User document has an embedded Alerts document. If I want to see if a given User has an alert with name I can do it two ways as far as I can tell -- in memory a la

alert = current_user.alerts.select{|a| a.name == params[:name]}.first

or via the actual document interface a la (note that I'm not 100% sure this is semantically valid but you get the point):

User.where('alerts.name' => params[:name], :id => current_user.id).first

There MU开发者_JS百科ST be a better way, something like

current_user.alerts.where(:name => params[:name])

perhaps? Or maybe I'm just not thinking about the problem right?


Nope. And I think this is the motivation:

In MongoMapper, queries on the database always return a root object. Allowing queries to return an embedded doc without its parent would be a break with that and make a lot of things more complicated (what if I call .parent inside that embedded doc?) so MongoMappers errs on the side of simplicity and doesn't pretend that things are something they aren't. Embedded docs are stored in an array inside the root doc in MongoDB, so MongoMapper gives you an array in Ruby.

So your two ways of doing it are the intended ways of doing it.

If you need some syntactic suger, it shouldn't be too hard to code up. You could extend Array or you could code a plugin to expand upon MongoMapper's proxy for embedded docs.


I think Mongoid supports this, see "Finding" in the manual for embedded docs.


You can do either:

User.where('alerts.name' => params[:name], :id => current_user.id).fields(:alerts).first.alerts.select{|u| u.name == params[:name]}

or

User.where('alerts.name' => params[:name], :id => current_user.id).fields(:alerts).alerts.select{|u| u.name == params[:name]}.first
0

精彩评论

暂无评论...
验证码 换一张
取 消