I have the following POJO.
@Document(collection = "questions") public class Question { @Id private String id; public List<String> getTags() { return tags; } public void setTags(List<String> tags) { this.tags = tags; } }
I am trying to implement a MongoRepository
query which finds all Question
s that contain a list of tags. I have tried the following:
@Repository public interface QuestionRepository extends MongoRepository<Question, String> { List<Question> findByTags(List<String> tags); }
but this is only working when the List
of tags that I'm passing to the method fully matches the list of tags assigned to the question in Mongo. E.g. if I have a question in Mongo with a list of tags [ "t1", "t2", "t3" ]
it is not returned by findByTags(List)
when I pass [ "t1", "t2" ]
to the method.
I have tried the following as well:
@Repository public interface QuestionRepository extends MongoRepository<Question, String> { @Query("{ tags: { $all: ?0 } }") List<Question> findByTags(List<String> tags); }
but then my war
could not be deployed to my servlet container at all. (I get the following error in that case:
The web application [backend] appears to have started a thread named [cluster-1-db:27017] but has failed to stop it. This is very likely to create a memory leak.
Would you please advise on how to implement that custom query?
MongoTemplate provides a simple way for you to save, update, and delete your domain objects and map those objects to documents stored in MongoDB. You can save, update and delete the object as shown below. MongoOperations is the interface that MongoTemplate implements.
@Document is an annotation provided by Spring data project. It is used to identify a domain object, which is persisted to MongoDB. So you can use it to map a Java class into a collection inside MongoDB. If you don't use Spring Data, you don't need this annotation.
MongoTemplate is a bit more lower level where you need to write your own queries. With embedded documents and denormalization it can be easier to write complex queries with MongoTemplate. For simple things I would use MongoRepository. I've seen some examples where both are used together in a hybrid approach.
Yes, DataNucleus JPA allows it, as well as to many other databases.
I will answer my own question as I have just found the answer by myself. The following section in the Spring Data MongoDB documentation lists all supported keywords that are used by Spring for its query derivation:
http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repository-query-keywords
The following implementation works for the use case described above:
@Repository public interface QuestionRepository extends MongoRepository<Question, String> { List<Question> findByTagsIn(List<String> tags); }
The CONTAINING keyword may also be used:
@Repository public interface QuestionRepository extends MongoRepository<Question, String> { List<Question> findByTagsContaining(List<String> tags); }
example and how it's mongo query looks like:
findByAddressesContaining(Address address) {"addresses" : { "$in" : address}}
This can also accept list of address in params.
See documentation: https://github.com/spring-projects/spring-data-mongodb/blob/e28bede416e4ddac19a35dc239388afc90b9cac4/src/main/asciidoc/reference/mongo-repositories.adoc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With