[SERVER-1367] create an $eq operator for queries that works similar to $gte and $lte Created: 06/Jul/10 Updated: 19/Dec/14 Resolved: 20/May/13 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Querying |
| Affects Version/s: | None |
| Fix Version/s: | 2.5.0 |
| Type: | New Feature | Priority: | Minor - P4 |
| Reporter: | Jeff McGee | Assignee: | Eliot Horowitz (Inactive) |
| Resolution: | Done | Votes: | 9 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
||||||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||||||
| Participants: | |||||||||||||||||||||||||||||
| Description |
|
We are writing a simple ORM for python called maroon. (http://github.com/nod/maroon) Our library builds mongo queries dynamically from python code that looks like this: Right now we have to treat equality as a special case when we do ands and ors: It it would make our code simpler and more consistent if $eq was an operator. For example: |
| Comments |
| Comment by NOVALUE Mitar [ 03/Nov/13 ] | |||||||||||
|
Isn't a workaround for this simply { x : { $in: [user_obj] }} ? | |||||||||||
| Comment by Remon van Vliet [ 15/May/13 ] | |||||||||||
|
+1. I actually think David's motivation is the most important one. | |||||||||||
| Comment by David Glasser [ 22/Apr/13 ] | |||||||||||
|
There's also a security implication here. Let's say you're writing a JSON-based API, that takes an untrusted user input, and you want to do a query to find the document in the Foo collection whose bar field equals the user's object. So you write `Foo.find( {"bar": userProvidedObject})`. Except... if the user-provided object has `$` keys (or is a regexp if that's possible in your RPC system, etc), you've now allowed an arbitrary query instead of just an equality lookup? Yes, you can validate first that `userProvidedObject` is a string, but what if you really do want to allow equality checks for non-scalar fields? If there was an `$eq` operator, then you would be able to write `Foo.find({"bar": {$eq: userProvidedObject}})`, and there would be no way for the untrusted user to perform an arbitrary non-equality query. But without this, you have to try to write your own code to check that `userProvidedObject` is not a Mongo query, which is an easy place to make mistakes. It's analogous to how while it's fine to write `printf("Foo")`, you typically want to avoid writing `printf(someString)` and want `printf("%s", someString)` instead. I don't mind that Mongo allows the current syntax for equality checks, but it would be nice to have a way to write your code such that you can explicitly say "I want to do an equality check against this field, please don't try to interpret this data as anything more complex than equality". BTW, this overlaps a bit with this section from the FAQ: http://docs.mongodb.org/manual/faq/developers/#dollar-sign-operator-escaping This statement in the FAQ under Querying seems to just be wrong: "Generally this is not a problem for queries that resemble { x : user_obj }: dollar signs are not top level and have no effect", since dollar signs in the keys of user_object have effect! | |||||||||||
| Comment by Russell Smith [ 16/Oct/12 ] | |||||||||||
|
I just ran in to this when helping someone on the mailing lists - $all with a single element array seems to be the nicest way of doing this, though it's not entirely obvious
$eq would do the same as either $gte + $lte or the same as $all with a single array element. | |||||||||||
| Comment by Giver of Rainy Darkness [ 01/Aug/11 ] | |||||||||||
|
But it only affects only parsing of query, optimizer runs after it. my patch just simplifies {$eq: x } to x. Why query optimizer will not work? | |||||||||||
| Comment by Eliot Horowitz (Inactive) [ 26/Jul/11 ] | |||||||||||
|
@giver - thanks for the patch. That doesn't work for the query optimizer, so isn't mergable in that form. | |||||||||||
| Comment by Giver of Rainy Darkness [ 25/Jul/11 ] | |||||||||||
|
I have created patch fixing this issue! | |||||||||||
| Comment by Mark Waschkowski [ 01/Feb/11 ] | |||||||||||
|
running into same issue with java | |||||||||||
| Comment by Vladimir Dronnikov [ 28/Jan/11 ] | |||||||||||
|
+1 – this would ease things and allow for more robust query composition. Also I don't get RegExp speciality – .find( {foo: /bar/}) but .find({foo:{$not:/bar/}}) instead of more rational imho .find({foo:{$ne:/bar/}}) Please, consider .find({foo:{$ne:/bar/}}) be not throwing but instead internally converted to corresponding $not TIA, |