mongodb 多表关联查询

news/2024/7/8 5:20:23

需求

mongodb库中有三张表,需求:查询表A中的数据,但这些数据的threadId字段,不能存在于表B和表C中,做一个过滤查询,需要分页和排序。

mongodb 命令实现

{
  "aggregate": "__collection__",
  "pipeline": [
    {
      "$match": {
        "open": 1,
        "closed": 0
      }
    },
    {
      "$lookup": {
        "from": "B",
        "localField": "threadId",
        "foreignField": "threadId",
        "as": "annotation"
      }
    },
    {
      "$unwind": {
        "path": "$annotation",
        "preserveNullAndEmptyArrays": true
      }
    },
    {
      "$match": {
        "$or": [
          {
            "annotation": null
          },
          {
            "annotation.reBacked": 1
          }
        ]
      }
    },
    {
      "$lookup": {
        "from": "C",
        "localField": "threadId",
        "foreignField": "threadId",
        "as": "queue"
      }
    },
    {
      "$unwind": {
        "path": "$queue",
        "preserveNullAndEmptyArrays": true
      }
    },
    {
      "$match": {
        "queue": null
      }
    },
    {
      "$sort": {
        "createTime": -1
      }
    },
    {
      "$skip": 0
    },
    {
      "$limit": 10
    }
  ]
}

其实就是多个$lookup的累加,需要配合$unwind使用。

java springboot 实现

pom.xml文件依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

接口实现代码如下:

    @Override
    public List<ThreadEntity> getThreadList(ThreadVo threadVo) throws Exception {
        String source = threadVo.getSource();
        Integer page = threadVo.getPage();
        Integer pageSize = threadVo.getPageSize();
        Integer type = threadVo.getType();

        LookupOperation lookupOperation1 = LookupOperation.newLookup()
                .from("B")
                .localField("threadId")
                .foreignField("threadId")
                .as("annotation");

        LookupOperation lookupOperation2 = LookupOperation.newLookup()
                .from("C")
                .localField("threadId")
                .foreignField("threadId")
                .as("queue");

        UnwindOperation unwind1 = UnwindOperation.newUnwind().path("annotation").noArrayIndex().preserveNullAndEmptyArrays();
        UnwindOperation unwind2 = UnwindOperation.newUnwind().path("queue").noArrayIndex().preserveNullAndEmptyArrays();

        Criteria criteria = Criteria.where("open").is(1).and("closed").is(0);
        AggregationOperation match = Aggregation.match(criteria);

        Criteria criteria1 = new Criteria();
        criteria1.orOperator(
                Criteria.where("annotation").is(null),
                Criteria.where("annotation.reBacked").is(1)
                );
        Criteria criteria2 = new Criteria().where("queue").is(null);
        AggregationOperation match1 = Aggregation.match(criteria1);
        AggregationOperation match2 = Aggregation.match(criteria2);
        AggregationOperation sort = Aggregation.sort(Sort.by(Sort.Order.desc(annotationLabelService.getGetConntentType(type))));
        AggregationOperation skip = Aggregation.skip((page - 1) * pageSize);
        AggregationOperation limit = Aggregation.limit(pageSize);

        Aggregation aggregation = Aggregation.newAggregation(match, lookupOperation1, unwind1, match1, lookupOperation2, unwind2, match2, sort, skip, limit);
        List<ThreadEntity> list = (List<ThreadEntity>) mongoUtils.lookUp(aggregation, "A", ThreadEntity.class);
        return list;
    }

http://www.niftyadmin.cn/n/3656122.html

相关文章

WPF,一次洗牌……

WPF,一次洗牌……昨天&#xff0c;在CSDN上看一篇孟岩的文章&#xff0c;谈及WPF带来的震撼&#xff0c;其实&#xff0c;WPF对今天的开发者来讲&#xff0c;已经不是很新的概念了&#xff0c;在MSN里&#xff0c;也与部分朋友交流对WPF的看法。最早体验WPF&#xff0c;也许是在…

Tangram开源版本发布

Tangram开源版本发布经过一段难忘的忙碌&#xff0c;Tangram的第一个完整版本杀青了。回想来到北京的几年&#xff0c;可谓感慨万千&#xff0c;开发产品是心志的磨练&#xff0c;这话没错&#xff01;经历身体与身心的煎熬&#xff0c;使我深刻的意识到勇者有畏&#xff0c;但…

【MQTT】Esp32数据上传采集:最新mqtt插件(支持掉线、真机调试错误等问题)

前言 这是我在Dcloud发布的插件-最完整Mqtt示例代码&#xff08;解决掉线、真机调试错误等问题&#xff09;&#xff0c;经过整改优化和替换Mqtt的js文件使一些市场上出现的问题得以解决&#xff0c;至于跨端出问题&#xff0c;可能原因有很多&#xff0c;例如&#xff0c;合法…

implement 和 extends 的区别

extends&#xff1a;拓展; 扩大范围 implement&#xff1a;使生效 ; 贯彻 ; 执行 重点&#xff1a; extends 用在同类之间。比如&#xff1a;classC 继承 classA&#xff0c;interFaceC 实现 interFaceA。implement 用在非同类之间。比如&#xff1a;classC 实现 interFaceA的…

让Internet Explorer成为你的软件集成平台

让Internet Explorer成为你的软件集成平台&#xff08;一&#xff09;最近一段时间&#xff0c;经常与朋友们探讨与浏览器相关的技术问题&#xff0c;多少年来&#xff0c;浏览器的问题一直是软件界的热点&#xff0c;无论是体验、操作习惯、安全&#xff0c;还是技术等问题&am…

@Async 异步不起作用

一、异步接口实现 java中的异步接口实现比较简单&#xff0c;主要有两步&#xff1a; 1、在ContentServiceApplication上添加EnableAsync。2、在需要异步的接口上添加Async接口。 // 第一步EnableAsync public class ContentServiceApplication {public static void main(St…

让Internet Explorer成为你的软件集成平台(二):献给VB Developer

Microsoft Visual Basic 6.0是Microsoft的一个经典作品&#xff0c;尽管争议颇多&#xff0c;个人认为VB6是一个十分优秀的开发工具。做为一款1998年的产品&#xff0c;VB6至今还被许多人所喜爱&#xff0c;笔者就是其中之一。针对COM组件开发&#xff0c;VB6非常方便&#xff…

pom文件 标签详解

<project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd"><!--父项目的坐标。如果…