关于Mongodb + java + 多表关联查询(MongoTemplate)

其实我也是第一次用,花了一天时间,总结下,自己算是留下文档,有问题的朋友也可以看看!废话不说,直接上代码

package com.hollysys.tn.service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import com.hollysys.tn.common.base.service.impl.BaseServiceImpl;
import com.hollysys.tn.entity.MaterialUsage;

import lombok.Data;

@Data
class ResultEntity{
    private Double amount;
    private String _id;
    private String name;
}


@Service
public class MaterialUsageService extends BaseServiceImpl<MaterialUsage>{
    @Autowired
    private MongoTemplate mongoTemplate;
    
    public List<MaterialUsage> query(Date beginDate, Date endDate) {
        
        LookupOperation lookupToLots = LookupOperation.newLookup().
                from("lots").//关联表名 lots
                localField("lotId").//关联字段
                foreignField("_id").//主表关联字段对应的次表字段
                as("entity");//查询结果集合名    
        LookupOperation lookupToMaterials = LookupOperation.newLookup().
                from("materials").//关联表名 materials
                localField("materialId").//关联字段
                foreignField("_id").//主表关联字段对应的次表字段
                as("bojo");//查询结果集合名    
        //Criteria criteriaToLots = new Criteria().and("entity.beginAt").lte(endDate).and("entity.endAt").gte(beginDate);
        Criteria criteriaToLots = new Criteria().and("entity.fillingRate").gte(0);
        AggregationOperation matchToLots = Aggregation.match(criteriaToLots);
        
        ProjectionOperation project  = Aggregation.project("entity._id","amount","bojo.name");
        project.andInclude("_id");
        Aggregation counts = Aggregation.newAggregation(lookupToLots,matchToLots,lookupToMaterials,project);
        
        List<Map> results =  mongoTemplate.aggregate(counts,"materialusage",Map.class).getMappedResults();
        System.out.println(results.size());

        //List<ResultEntity> results =  mongoTemplate.aggregate(counts,"materialusage",ResultEntity.class).getMappedResults();
        
        System.out.println(results.get(0).getName()); 
        return null;
    }
}
包都上了,我下面把代码解析下,我用的是springBoot哦!
  1. lookupToLots 这是主表materialusage关联---->lots表,具体看代码后面注释。

  2. lookupToMaterials 这是主表materialusage关联---->materials表,具体看代码后面注释

  3. matchToLots 是我子表需要的过滤的条件。

  4. ProjectionOperation 这个是选择你想要的字段,可以看到 bojo.name(子表)。

  5. project.andInclude("_id"); 这个注意了,是剃掉ID,有个坑就是:ProjectionOperation project = Aggregation.project("entity._id","amount","bojo.name").andInclude("_id"); 这样是剃不掉的。可以测试下。

  6. Aggregation counts = Aggregation.newAggregation(lookupToLots,matchToLots,lookupToMaterials,project);

注意:这段代码主要注意后面括号里面的东西的顺序,按照你需要关联的表的顺序来吧
  1. List<ResultEntity> results = mongoTemplate.aggregate(counts,"materialusage",Map.class).getMappedResults();
    这段代码就是最后的查询了。至于返回的值类型,我是用自己设置的ResultEntity对象,见代码头部。

  2. 对于返回值,我再补充点,我本来用的Map泛型接受的,其实我的返回值是这样的:
    [{amount=100.0, _id=[20190612S], name=[自动打包带]}, {amount=100.0, _id=[20190612S], name=[纸箱空白条码]}]
    你会注意到里面有两个数组,因为那两个值分别是另两个表的两个值,我尝试用对象ResultEntity接受,很有意思,看代码:
    [ResultEntity(amount=100.0, _id=20190612S, name=自动打包带), ResultEntity(amount=100.0, _id=20190612S, name=纸箱空白条码), ResultEntity(amount=100.0, _id=20190612S, name=胶纸), ResultEntity(amount=100.0, _id=20190612S, name=纸箱)]

哈哈,对象,这个我们处理数据随心所欲。 控制台直接打出get方法 —>自动打包带就这么多吧,有问题可以给我留言,转载请注明出处
  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Java 中使用 MongoDB 进行多表关联查询可以通过使用 MongoDB 的聚合管道(Aggregation Pipeline)来实现。聚合管道是一系列操作步骤,可以将多个表的数据进行关联和处理。 下面是一个示例代码,展示了如何在 Java 中使用 MongoDB 的聚合管道进行多表关联查询: ```java import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Filters; import com.mongodb.client.model.LookupOperation; import org.bson.Document; public class Main { public static void main(String[] args) { // 连接 MongoDB try (MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017")) { MongoCollection<Document> ordersCollection = mongoClient.getDatabase("mydb").getCollection("orders"); MongoCollection<Document> customersCollection = mongoClient.getDatabase("mydb").getCollection("customers"); // 定义聚合管道操作 LookupOperation lookupOperation = LookupOperation .from("customers", "customerId", "_id", "customerInfo"); // 构建聚合管道 AggregateIterable<Document> result = ordersCollection.aggregate(Arrays.asList( Aggregates.match(Filters.eq("status", "completed")), lookupOperation )); // 遍历查询结果 for (Document document : result) { System.out.println(document); } } } } ``` 上述示例代码中,我们假设有两个集合:`orders` 和 `customers`。`orders` 集合中的每个文档包含一个 `customerId` 字段,该字段与 `customers` 集合中的 `_id` 字段关联。我们使用 `LookupOperation` 来进行关联查询,并使用 `match` 操作来过滤出状态为 "completed" 的订单。 请注意,这只是一个简单的示例,实际的多表关联查询可能需要更复杂的聚合管道操作来满足特定的需求。你可以根据自己的实际情况进行相应的调整和扩展。 希望能帮助到你!如果有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值