Spring数据mongodb过滤字符串集合中的嵌套对象ID

Posted

技术标签:

【中文标题】Spring数据mongodb过滤字符串集合中的嵌套对象ID【英文标题】:Spring data mongodb filter nested object id in collection of String 【发布时间】:2022-01-09 12:38:04 【问题描述】:

我想使用 Mongodb 聚合匹配操作通过 String 中多个嵌套对象的对象 ID 过滤 mongodb 集合。但是spring data mongodb不会在匹配操作中将String值转换为对象Id。

我能够通过字符串值中的多个文档 ID(主键,而不是嵌套对象的对象 ID)过滤文档,而没有任何问题,因为 Spring 数据 mongodb 将字符串值转换为 oid:

 "_id" :  "$in" : [ "$oid" : "61a31853d268434139e7fc11",  "$oid" : "61a31853d268434139e7fc12"]

我想要达到的目标如下:

db.getCollection('products').aggregate(
[
     "$match" :  "$and" : [ "type._id" :  "$in" : [ 
       ObjectId("618b99a3b4c24465b074b246"), 
       ObjectId("60afc0920dab8b6d3ac26355") 
    ] ]
])

但我总是得到以下信息:

    db.getCollection('products').aggregate(
    [
         "$match" :  "$and" : [ "type._id" :  "$in" : [
[ "$oid" : "618b99a3b4c24465b074b246",  "$oid" : "60afc0920dab8b6d3ac26355"]
        ]]
    ])

Spring data mongodb 为 $in json 中的 OID 生成二维数组

我的 Mongodb 实体:

@Document(collection = "products")
public class Product 

    @Id
    private String id;

    @NotNull
    private ProductType type;  

    public String getId() 
        return id;
    

    public void setId(String id) 
        this.id = id;
    

    public Type getType() 
        return type;
    

    public void setType(ProductType type) 
        this.type = type;
    



@Document(collection = "product_types")
public class ProductType 

    @Id
    private String id;

        public String getId() 
        return id;
    

    public void setId(String id) 
        this.id = id;
    


我执行聚合的java代码:

List<String> typeIds = Arrays.asList("618b99a3b4c24465b074b246", "60ad10ffc723877d8a977149");
List<AggregationOperation> aggregateOperations = new ArrayList<>(); 
Criteria criteria = Criteria.where("type._id").in(typeIds.stream().map(t -> new ObjectId(t)).collect(Collectors.toList()));
aggregateOperations.add(Aggregation.match(criteria));

Aggregation aggregation = Aggregation.newAggregation(aggregateOperations);  
mongoTemplate.aggregate(aggregation, "products", ProductListDTO.class);

mongodb采集数据如下:


    "_id" : ObjectId("61a31853d268434139e7fc11"),
    "type" : 
        "_id" : ObjectId("618b99a3b4c24465b074b246")
    

【问题讨论】:

【参考方案1】:

它按预期工作。当您记录聚合管道时,它会写入 $oid: 'hex'date 也是如此)。

在内部驱动程序搜索为 ObjectId(...) 符合预期:

//WHEN
Criteria criteria = Criteria.where("type._id")
    .in(typeIds.stream().map(ObjectId::new).collect(Collectors.toList()))
    .and("date").is(new Date(currDate));

//Searches:
Document$match=Documenttype._id=Document$in=[618b99a3b4c24465b074b246], date=Tue Dec 14 01:53:09 CET 2021

//LOG:

    "aggregate": "__collection__",
    "pipeline": [
        
            "$match": 
                "type._id": 
                    "$in": [
                        
                            "$oid": "618b99a3b4c24465b074b246"
                        
                    ]
                ,
                "date": 
                    "$date": "2021-12-14T00:53:09.817Z"
                
            
        
    ]

【讨论】:

以上是关于Spring数据mongodb过滤字符串集合中的嵌套对象ID的主要内容,如果未能解决你的问题,请参考以下文章

使用 mongoose nodejs 过滤 mongodb 数据库

使用spring boot将大量数据从一个集合复制到Mongodb中的另一个集合

猫鼬中的嵌套子模式

mongodb - 按字符串数组过滤集合包含“”

通过 spring-data 迭代 MongoDB 中的大型集合

如果字段数组和参数数组相交,则过滤 MongoDb 集合