Repository query with a List parameter in Spring D

2020-05-20 07:41发布

问题:

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 Questions 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?

回答1:

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);
}


回答2:

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