【问题标题】:Is there a way to return a whole different data structure by using mongodb aggregations and projections?有没有办法通过使用 mongodb 聚合和投影来返回完全不同的数据结构?
【发布时间】:2020-12-05 00:07:11
【问题描述】:

假设我有以下具有以下结构的 mongodb 集合:

mongodocument:
   _id: xxx
    A: "CLEYMAR_COMPANY"
    category: Object
        ENGINEER: Object
        ARQUITECT: Object

根据公司,职业可以为空。

我想根据以下查询返回一个数据结构:

根据给定 A 的键列表的类别返回结果集,例如

["CLEYMAR_COMPANY", "VIC_COMPANY"] 

还有一个类别列表,例如

["ENGINEER", "ARQUITECT"]

结果:

ENGINEER_RESULT :  [ENGINEER(corresponding to CLEYMAR COMPANY)      ENGINEER(corresponding to VIC_COMPANY)]

 ARQUITECT_RESULT: [ARQUITECT(corresponding to VIC COMPANY)]. 
    
    

【问题讨论】:

    标签: java mongodb spring-boot spring-data-mongodb


    【解决方案1】:

    您需要自动装配 mongo 模板。

    @Autowired
    private MongoTemplate mongoTemplate;
    
    • $match 匹配公司
    • $addFields 覆盖类别字段。由于我们将动态键作为类别中的类别,因此我们将使用$objectToArray 将其与键值对组成数组。然后用职业列表过滤数组。一旦我们过滤,它将给出数组。为了使其成为原始形式,我们使用$arrayToObject

    由于spring数据没有提供任何$addFields,我们需要使用TRICK TO CONVERT MONGO SHELL QUERY INTO EQUIVALENT JAVA OBJECTS

    方法是

    public List<Object> test(List<String> companies,List<String> professions ) {
    
        Aggregation aggregation = Aggregation.newAggregation(
            match(Criteria.where("A").in(companies)),
            a-> new Document("$addFields",
                    new Document("category",
                            new Document("$arrayToObject",
                                new Document("$filter"
                                    new Document()
                                    .append("input",new Document("$objectToArray","$category"))                     
                                    .append("cond",
                                        new Document("$in",Arrays.asList("$$this.k",professions))
                                    )
                                )
                            )                                       
                )
            )
    
        ).withOptions(AggregationOptions.builder().allowDiskUse(Boolean.TRUE).build());
    
        return mongoTemplate.aggregate(aggregation, mongoTemplate.getCollectionName(YOUR_COLLECTION.class), Object.class).getMappedResults();
    
    }
    

    工作Mongo playground

    注意:Java 代码未经测试。它是基于工作 mongo 查询编写的

    【讨论】:

    • 您好 Varman,感谢您的回答。第一个问题,new Document 是做什么的?
    • Java 文档 - 将文档表示为 Map。所有迭代器都会按插入顺序遍历元素,就像 LinkedHashMap 一样。
    猜你喜欢
    • 2016-02-28
    • 2021-05-19
    • 2015-07-17
    • 1970-01-01
    • 2015-04-04
    • 2018-05-06
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多