2

I have set up MongoDB following this tutorial

http://www.littlelostmanuals.com/2011/09/spring-mongodb-type-safe-queries.html

Everything works as expected but now I'm stuck at a point where I want to be able to query on multiple fields.

Currently I have repository interfaces for each type I'm saving and can search on a single field fine.

public interface StartedEventRepository extends 
    MongoRepository<DatablockStartedEvent, String>,
    QueryDslPredicateExecutor<DatablockStartedEvent> { 

}

Below is the query for a single parameter.

        return startedEventRepo
            .findOne(QDatablockStartedEvent.datablockStartedEvent.searchId
                    .eq(searchId));

Is it possible to create a Query object where I can say something similar to the following.

if(someName != null){
    query.where(QMyClass.name.eq(someName));
}
if(someTime != null){
    query.where(QMyClass.time.eq(someTime));
}

List result = query.list();

I've tried looking at the MongodbQuery but I couldn't get it to work. Any ideas?

I saw an example http://www.mkyong.com/mongodb/spring-data-mongodb-update-document/ but this uses the mongoTemplate. Is there no way to achieve this through the repositories and if not, are they useless?

2 Answers 2

10

It should be possible. Something like this maybe

BooleanBuilder builder = new BooleanBuilder();

if(someName != null){
    builder.and(QMyClass.name.eq(someName));
}
if(someTime != null){
    builder.and(QMyClass.time.eq(someTime));
}

repository.findAll(builder.getValue())
Sign up to request clarification or add additional context in comments.

4 Comments

This worked exactly how I wanted it to. Why did I spend so much time messing around with MongodbQuery<T> and all the stupid classes it needs. Thanks very much.
com.mysema.query.mongodb.MongodbQuery<T> is a low level query class and should be used via high level adapters, either something from Spring Data or via Querydsl Morphia support
Thanks, I'll have to read up about it in more detail. This is my first time with mongo and spring data so I'm still learning. Prior to this I was just using MyBatis and Hibernate.
Improvement: instead of builder.getValue(), you can simply pass 'builder' to the repository.findAll method as BooleanBuilder implements the com.querydsl.core.types.Predicate.
1

Without ever working with Spring Data, I would guess from Reading this http://static.springsource.org/spring-data/data-document/docs/1.0.0.M2/reference/html/#mongodb.repositories.queries that you simply declare a method in your repository where the Method name tells your query structure (this guess is supported through example 4.3 on the same site). Not sure If you can generate dynamic Queries, this was the only one a quick search revealed.

3 Comments

I've tried this, and it works quite well but it requires that the key is always present. For example if I add findBy(String id, String loginId, String searchId) then I must always provide the field id or it will throw a nullpointer exception. It is possible to search directly without providing the id field so I was suprised to see it didn't work. Almost exactly what I wanted. I'll have to do more investigation first only touched on it today.
Just tested it by rearranging the parameters. So I do findBy(String loginId, String id, String searchId) and now it is required that I provid loginId, therefore I must always provide the first parameter. Doesn't quite fit with what I need.
Sorry can't help you further, was just summing up what a quick look into the docs revealed to me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.