MongoDB supports DbRef fields when one document needs to refer to another in a standard way -- see http://www.mongodb.org/display/DOCS/Database+References.
It would be really excellent if QueryDSL could support doing queries where fields that represented DbRefs were automatically traversed during a query. For example (using the Spring Data Mongodb annotations):
@Document
Obj1 {
@DbRef Obj2 obj2Ref;
}
@Document
Obj2 {
String foo;
}
then one could do the following query:
.where(QObj1.obj2Ref.foo.eq("Bob"))
.list()
This sounds like a valid addition, but might be quite difficult to implement, since dbref on database level doesn't seem to be supported.
So it's multiple nested queries or maybe map-reduce. Do you see other implementation options?
Agreed, I don't see any other option than nested queries or map-reduce. I think as long as it is made clear in the documentation, I don't see an issue with using multiple queries to satisfy the query DSL. I suspect multiple queries will be faster than map-reduce.
Here I'd also prefer to apply some more explicit joining
query.join(doc.obj2Ref, obj2).on(obj2.foo.eq("Bob"))
This could be continued with a where-clause if additional constraints are needed. This separates the query layers quite clearly. Is something like this ok?
Yes, that would work nicely I think.
The first working version is ready. The algorithm goes through the joins from last to first and provides as an output an extended filter condition for the first query. This will probably work quite well for many-to-one kind of relations. Maybe not so well for others.
Here are some new tests
@Test
public void Double2() {
assertEquals("Mike", where()
.join(user.friend(), friend).on(friend.firstName.eq("Mary"))
.join(user.enemy(), enemy).on(enemy.firstName.eq("Ann"))
.singleResult().getFirstName());
}
@Test
public void Deep() {
// Mike -> Mary -> Jane
assertEquals("Mike", where()
.join(user.friend(), friend).on(friend.firstName.isNotNull())
.join(friend.friend(), friend2).on(friend2.firstName.eq("Jane"))
.singleResult().getFirstName());
}
The syntax is a little bit verbose, but the execution semantics are quite simple and transparent, so it could be released like this. Any objections?
I haven't had a chance to try out the snapshot yet, but the tests look good.
Released in 2.5.0
@rocketraman Did you have the chance to try out the feature? Anything else that should be added for Querydsl Mongodb?
Hey,
i would like to do the same with list of @DBRef like this :
@DBRef
private List<FileSys> registeredChannels = new ArrayList<FileSys>();
my request > QProfile.profile.registeredChannels.contains(channel)
(channel is an FileSys object)
always return an empty list
please, help me
@xavier59 Could you open a new ticket for this?
Something like "Support for DBRef List traversal in Querydsl Mongodb"
@timowest I haven't had a chance to try out the new feature yet... however FYI the spring-data mongodb guys are thinking about how to use this from the spring-data mongodb querydsl integration. You might have some useful thoughts on it...
Thanks, I will take a look
@timowest is there a possibility to construct query with OR between join predicates?
public class Car {
BigInteger id;
String name;
@DBRef
Engine engine;
@DBRef
Radio radio;
}
public class Radio {
BigInteger id;
Boolean rds;
}
public class Engine {
BigInteger id;
Integer power;
}
And I would like to get cars with engine more then 100 power or cars with radios with rds.
@noter At the moment not.
@timowest finally
query
.where(QObj1.obj2Ref.foo.eq("Bob"))
.list()
can this realized??
+1 looking for this easier query syntax
Most helpful comment
+1 looking for this easier query syntax