Possible with the Ruby driver ? { keywords : { $in : ["a", "b"] }, keywords : { $in : ["c, d"] } }

24 views
Skip to first unread message

nicolas_

unread,
Jul 25, 2009, 1:33:10 PM7/25/09
to mongodb-user
Hi,

Does anynoe know if it's posibble to add multiple conditions for the
same key with the Ruby Driver ?

In the mongo console, I can do a query like:

db.posts.find( { keywords : { $in : ["a", "b"] }, keywords : { $in :
["c, d"] } } )

It finds all documents containing "a" or "b" , and containing "c" or
"d".

The problem is that the Ruby driver takes a Hash as a selector, so I
can't find a way to give it multiple conditions with the same key.

Thanks,

Nicolas

dwight_10gen

unread,
Jul 25, 2009, 3:52:37 PM7/25/09
to mongodb-user
probably not possible in that way. this is a limitation of the query
objects at this point - fully generalized boolean and & or aren't
there yet (this is very likely long term though)

however, the is another way to do it - $where - which is a good way to
do generalized expressions. You'll generally want one term that is
not in the $where clause, so that the query optimizer has something to
go by.

db.posts.find( { keywords : { $in : ["a", "b"] }, $where : "function()
{ return this.keywords.contains("c","d"); }" } )

nicolas_

unread,
Jul 26, 2009, 4:21:11 AM7/26/09
to mongodb-user
Thanks. I'll check the impact on performance.

In the meantime, would it be possible to directly send string queries
with the same format than in the Mongo console ?

A ruby code like:

collection.find( '{ keywords : { $in : ["a", "b"] }, keywords :
{ $in : ["c, d"] } }', :limit => 10 )

Michael Dirolf

unread,
Jul 27, 2009, 10:10:14 AM7/27/09
to mongod...@googlegroups.com
This is a limitation of the way we represent BSON documents using Ruby
hashes (same applies for Python dicts and maybe PHP arrays, although
I'm not positive about that).

In order to allow these types of queries we'll need to make changes to
the BSON encoder and probably add a new class that let's us represent
hash-like things with duplicate keys - your suggestion of a string
representation is one possibility. This is sort of a big change since
it will affect several of the drivers (would be nice to make this
change in a consistent way across languages).

I've created a JIRA for this under RUBY-20 (even though it applies to
other languages), so feel free to comment there.

austinfromboston

unread,
Jul 27, 2009, 12:21:13 PM7/27/09
to mongodb-user
For what it's worth, the idiomatic Ruby way to handle this would be to
allow an array of hashes as a value, like:

db.posts.find( { keywords => [ { :'$in' => ["a", "b"] }, { :'$in' =>
["c, d"] } ] } )

seems like Python and PHP should be able to handle this syntax as
well.

nicolas_

unread,
Jul 27, 2009, 12:37:25 PM7/27/09
to mongodb-user
Thanks a lot, I added a comment about the "idiomatic way to handle
this in Ruby", as posted by "austinfromboston".

Christian "Webstar" Hoeppner

unread,
Jul 27, 2009, 1:19:00 PM7/27/09
to mongod...@googlegroups.com
Hey there,

I found that the methods MongoRecord::Base::has_many and ::has_one
disalow the target class to have ::Subobject among it's ancestors. This
has had me wondering what use Subobjects actually are, and how to use
them. I think I may have a use-case for it, where a model holds an array
of hashes, basically mini-objects with the same properties in hash form.
I guess Subobjects represent embedded document collections somehow, I'm
just not clear on how to use them, as the documentation on them is
rather scarce.

Could anyone come up with a short example?

Michael Dirolf

unread,
Jul 27, 2009, 2:19:42 PM7/27/09
to mongod...@googlegroups.com
has_one and has_many shouldn't disallow Subobjects. A good example of
this is the Student -> Address example in the test code included with
MongoRecord. Basically the purpose of a Subobject is just to disallow
certain operations so that you don't accidently use it as a full
fledged document, only embedded.

If you're running into issues with has_one or has_many and Subobjects
a test case would be appreciated.

Christian "Webstar" Hoeppner

unread,
Jul 27, 2009, 4:21:27 PM7/27/09
to mongod...@googlegroups.com
The RDoc states explicitly that Subobjects are disallowed, but when I
tried it out it worked just fine. The only actual flaw I found is that
::Subobject doesn't override the ::create method, and if you happen to
use it instead of ::new it will raise an exception when ::create tries
to access the _id. The rdoc should be changed, as well as ::create be
overridden as no-op or to raise a more verbose exception.

Michael Dirolf escribió:

Michael Dirolf

unread,
Jul 27, 2009, 5:15:49 PM7/27/09
to mongod...@googlegroups.com
Where are you seeing docs that say has_many and has_one can't be
Subobjects? The docs I'm looking at say that it "need not be a
MongoRecord::Subobject", but don't say that it can't be. Is there
something else you saw that I'm missing?

Overriding create to raise an exception now - thanks.

Christian "Webstar" Hoeppner

unread,
Jul 27, 2009, 5:52:21 PM7/27/09
to mongod...@googlegroups.com
Ah well, I interpreted it wrong then. A more clear wording would be
"doesn't need to be" instead of "need not be". However, to make it even
more clear, I'd have it state that you can use both Subobjects or Base
objects.

Michael Dirolf escribió:

Michael Dirolf

unread,
Jul 27, 2009, 5:57:34 PM7/27/09
to mongod...@googlegroups.com
Agreed - I'll change this now. The create issue you mentioned earlier
should be resolved in master.

Christian "Webstar" Hoeppner

unread,
Jul 27, 2009, 6:37:50 PM7/27/09
to mongod...@googlegroups.com
I'm using the gem version, but I will switch to master later. Does the
mongo driver need to be HEAD as well? And the database engine?

Also, thank you for the quick inclusion =)

Michael Dirolf escribió:

dwight_10gen

unread,
Jul 27, 2009, 7:52:00 PM7/27/09
to mongodb-user
Perhaps we shouldn't duplicate keys in BSON -- even though it kind of
works today -- to keep it as similar to JSON as possible.

The JSON RFC says

The names within an object SHOULD be unique.

Debatable.

Christian "Webstar" Hoeppner

unread,
Jul 27, 2009, 8:49:50 PM7/27/09
to mongod...@googlegroups.com
Oh, by the way. Since you're on it, you might want to make belongs_to an
alias to has_one, since they basically do the same. And in most cases,
when an object has_one of another object it usually belongs to that
object anyway.

Christian "Webstar" Hoeppner escribió:

Michael Dirolf

unread,
Jul 28, 2009, 10:19:13 AM7/28/09
to mongod...@googlegroups.com
I just bumped the gem to 0.4.1 so you should be able to just update
instead of switching to master. It depends on the new version of the
Ruby driver (0.10 - also just bumped). Everything should work on
MongoDB 0.9.6

Michael Dirolf

unread,
Jul 28, 2009, 10:48:19 AM7/28/09
to mongod...@googlegroups.com
I'm not sure that those are supposed to do the same thing. AFAIK
belongs_to is always supposed to be used in associated classes, where
has_one would be used in the base class to establish a 1:1
relationship. You can see the test code in MongoRecord (address.rb and
student.rb) for an example of this.

austinfromboston

unread,
Jul 28, 2009, 12:11:40 PM7/28/09
to mongodb-user
The difference is in the location of the foreign key. has_one implies
that something out there has a reference to the current object.
belongs_to tells you that the current object has a value referencing a
foreign object.

On Jul 27, 5:49 pm, "Christian \"Webstar\" Hoeppner"

Christian "Webstar" Hoeppner

unread,
Jul 28, 2009, 1:26:39 PM7/28/09
to mongod...@googlegroups.com
Yet ::belongs_to is a no-op at the moment, so we have to resort to
::has_one, which in this case would be semantically incorrect.

Michael Dirolf escribió:

Michael Dirolf

unread,
Jul 28, 2009, 1:29:21 PM7/28/09
to mongod...@googlegroups.com
belongs_to should always be paired with a has_one or a has_many in the
associated class. so belongs_to is a no-op while the other methods
have implementations - the base model (has_one or has_many) is doing
the work. does this explain things better?

Christian "Webstar" Hoeppner

unread,
Jul 28, 2009, 2:56:51 PM7/28/09
to mongod...@googlegroups.com
Yes, this has indeed cleared things up. Thanks.

Michael Dirolf escribió:
Reply all
Reply to author
Forward
0 new messages