【问题标题】:Make mongo query in spring where Document contain array在 Spring 中进行 mongo 查询,其中 Document 包含数组
【发布时间】:2016-01-19 00:01:03
【问题描述】:

我正在使用 spring 和 mongo 进行 API 开发,文档结构如下:

Document-1
myId:1
array:['abc','jkl','xyz']

Document-2
myId:3
array:['qwe','mnp','xyz']

Document-3
myId:3
array:['ped','abc','xyz']

My url : localhost:8080/array=xyz
expected : document-1,document-2,document-3

My url: localhost:8080/array=xyz,abc
exoected: document-1,document-3

简而言之,我希望结果中的所有文档都包含所有逗号分隔的array 变量。

spring 是否提供了像 @Query 注解这样的内置支持?

或者我怎样才能做到这一点?

【问题讨论】:

    标签: spring mongodb spring-mvc


    【解决方案1】:

    您实际上想使用 $all 运算符来获得所需的结果。在mongo shell中,下面的操作会带上文件:

    填充测试集合

    db.test.insert([
        {
            _id: 1,
            myId: 1,
            array: ['abc','jkl','xyz']
        },
        {
            _id: 2,
            myId: 3,
            array: ['qwe','mnp','xyz']
        },
        {
            _id: 3,
            myId: 3,
            array:['ped','abc','xyz']
        }
    ])
    

    运行操作

    > db.test.find({"array": { "$all": ["xyz"] }})
    { "_id" : 1, "myId" : 1, "array" : [ "abc", "jkl", "xyz" ] }
    { "_id" : 2, "myId" : 3, "array" : [ "qwe", "mnp", "xyz" ] }
    { "_id" : 3, "myId" : 3, "array" : [ "ped", "abc", "xyz" ] }
    
    > db.test.find({"array": { "$all": ["abc", "xyz"] }})
    { "_id" : 1, "myId" : 1, "array" : [ "abc", "jkl", "xyz" ] }
    { "_id" : 3, "myId" : 3, "array" : [ "ped", "abc", "xyz" ] }
    

    与 Spring Data MongoDB 中的 @Query 注释一样,我没有对此进行测试,但您可能想尝试以下自定义查询实现示例

    @Document(collection="test")
    class Test {
        int myId;
        String[] array;
    }
    
    public interface TestRepository extends MongoRepository<Test, Integer> {
        @Query(value = "{ 'array' : {$all : [?0] }}")
        public List<Test> findAnyOfTheseValues(String[] arrayValues);
    }
    

    如果上述方法不适合您,您可能需要创建一个自定义接口和您的实现类来执行自定义查询。例如,创建一个名称附加自定义的接口:

    public interface TestRepositoryCustom {
        public List<Test> findAnyOfTheseValues(String[] arrayValues); 
    }
    

    修改TestRepository,增加TestRepositoryCustom接口进行扩展:

    @Repository
    public interface TestRepository extends TestRepositoryCustom, MongoRepository {
    
    }
    

    创建你的实现类来实现TestRepositoryCustom接口中定义的方法。

    public class TestRepositoryImpl implements TestRepositoryCustom {
    
        @Autowired
        MongoTemplate mongoTemplate;
    
        @Override
        public List<Test> findAnyOfTheseValues(String[] arrayValues) {
            return mongoTemplate.find(
                Query.query(Criteria.where("array").all(arrayValues)), Test.class);
        }
    }
    

    【讨论】:

    • 我已经测试了@Query,但它并没有按照应有的方式工作。我为 localhost:8080/array=abc,xyz 得到的结果。它只给出具有 "array":["abc","xyz"] 的文档。甚至顺序也很重要。并且不给出包含数组的文档:["abc","xyz","ped"]。测试第二个解决方案
    • 谢谢,很好的答案,但是不区分大小写呢,有可能吗? +1
    • 我测试了接受的答案,但它不能与 Spring 存储库一起正常工作。该方法生成的查询看起来像: { "tags" : { "$all" : [["tag1"]] } } 它需要最小的调整 java @Query(value = "{ 'tags' : {$all : ?0 }}") List&lt;Sampling&gt; findWithTags(String[] arrayValues); 来生成像 { "tags" : { "$全部" : ["tag1"] } }
    • where.all 还是where.in
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    相关资源
    最近更新 更多