MongoTemplate 至少匹配我传递的值的查询数组

Posted

技术标签:

【中文标题】MongoTemplate 至少匹配我传递的值的查询数组【英文标题】:MongoTemplate Query array that match at least the values I'm passing 【发布时间】:2022-01-02 03:59:40 【问题描述】:

如果我将文档定义为

[
  
    "title": "title",
    "tags": [ "cool", "amazing", "funny" ]
  ,
  
    "title": "another title",
    "tags": [ "nice", "amazing", "funny" ]
  
]

我希望能够使用 MongoTemplate 进行查询,以便传递像 ["cool","amazing"] 这样的值列表,并返回上面的第一个集合,而不是第二个集合。 对于我要实现的目标, $in 条件似乎还不够。 我尝试了 $all 条件,并从 Mongo 控制台按我的需要工作,但在我的代码中某些东西不起作用,我的查询需要很长时间才能详细说明。使用 $in 运算符,我的代码运行得很快。 我的存储库中的方法(出于其他原因,我必须进行如下聚合):

public Page<MyDocument> findByProperties(String title, List<ObjectId> tags, Pageable page) 
        final List<Criteria> criteria = new ArrayList<>();
        Aggregation aggregation = null;

        
        if (title != null && !title.isEmpty()) 
            criteria.add(Criteria.where("title").is(title));
        
        
        if (tags != null && !tags.isEmpty()) 
            criteria.add(Criteria.where("MyBook.tags").all(tags));
        

        if (!criteria.isEmpty()) 
            aggregation = Aggregation.newAggregation(
                    Aggregation.lookup("from_collection", "_id", "idParent", "MyBook"),
                    Aggregation.unwind("MyBook"),
                    Aggregation.match(new Criteria().andOperator(criteria.toArray(new Criteria[0]))),
                    Aggregation.skip(page.getOffset()),
                    Aggregation.limit(page.getPageSize()),
                    Aggregation.sort(page.getSort())
            );
         else 
            aggregation = Aggregation.newAggregation(
                    Aggregation.lookup("from_collection", "_id", "idParent", "MyBook"),
                    Aggregation.unwind("MyBook"),
                    Aggregation.skip(page.getOffset()),
                    Aggregation.limit(page.getPageSize()),
                    Aggregation.sort(page.getSort())
            );
        

        List<MyDocument>  results  = mongoTemplate.aggregate(aggregation, "my_document", MyDocument.class).getMappedResults();

        return PageableExecutionUtils.getPage(results, page,
                () -> (long)results.size());
     

看着this的回答,我试过了

criteria.add(Criteria.where("MyBook.tags").in(tags).all(tags));

但没有任何改变,查询需要很长时间,而不是预期的输出。 请问有什么想法吗?谢谢!

【问题讨论】:

我认为您只需将criteria 变量传递给Aggregation.match( 嗨@prasad_,我正在测试条件不为空的情况:首先,如果有 Aggregation.match() 【参考方案1】:

要查找 tags 数组字段是否包含 youe 数组的所有成员,您可以使用波纹管,如果您需要它在聚合管道中使用第二个。

在您的查询中,您有更多阶段和更多代码,如果您想询问更多是否可以提供 JSON 格式的示例数据和预期输出,以及您想要做什么,以便人们可以提供帮助。

查询1

使用$all 运算符查找

Test code here

db.collection.find("tags": "$all": ["cool","amazing"])

查询2

具有集合差异的聚合解决方案

Test code here

aggregate(
["$match": 
    "$expr": 
      "$eq": ["$setDifference": [["cool", "amazing"], "$tags"], []]])

【讨论】:

您好 Takis,感谢您的提示!我需要的是用 Java 来做,而不是通过已经可以工作的 Mongo 控制台。使用 MongoTemplate 我必须使用投影,在我的情况下,我宁愿坚持使用聚合。对于代码示例,我只需要加入两个集合(聚合)并查询我加入的“MyBook”集合中存在的数组

以上是关于MongoTemplate 至少匹配我传递的值的查询数组的主要内容,如果未能解决你的问题,请参考以下文章

开发中使用mongoTemplate进行Aggregation聚合查询

SQL 查询 - 匹配 5 中至少 4 个值的条件

MongoDB JAVA API Filters

MongoTemplate:匹配某个标准的文档的键值总和

将 MongoTemplate 传递给自定义存储库实现

SQL 列名或提供的值的数量与表定义不匹配