spring-boot-date(mongoTemplate)、mongodb聚合管道求交集、并集、补集

这里给出求交集的例子,其他两个将关键字替换即可

需求:根据自定义数据集合与数据库中指定集合的交集,
得到一个交集集合commonToBoth,
然后得到commonToBoth集合的commonToBothSize(此集合长度)
根据集合长度降序排列
取数据前30

$setIntersection 交集
$ setUnion 并集

其他集合操作符号参考官方文档
https://docs.mongodb.com/manual/reference/operator/aggregation/setUnion/

原始测试数据

{
    "_id" : "QR205",
    "type" : "车船税",
    "title" : "新购置的车辆怎样缴纳车船税?",
    "content" : "根据\"R004301300\",\"R003901100\",",
    "items" : [ 
        "R004301300", 
        "R003901100"
    ],
    "visitNum" : 0,
    "createTime" : ISODate("2018-10-17T17:23:30.753+08:00"),
    "valid" : true,
    "excelType" : "车船税",
    "_class" : "xxxxxxx",
    "darkTitle" : "购置 缴纳 新购 车辆 车船税 车船 怎样 购置的车辆 新购置 ",
    "mapDarkTitle" : [ 
        {
            "word" : "购置",
            "weight" : 0.26167237114963
        }, 
        {
            "word" : "缴纳",
            "weight" : 0.144611921887102
        }, 
        {
            "word" : "新购",
            "weight" : 0.610634741922963
        }, 
        {
            "word" : "车辆",
            "weight" : 0.403475579598236
        }, 
        {
            "word" : "车船税",
            "weight" : 0.792685592072759
        }, 
        {
            "word" : "车船",
            "weight" : 0.484382636624167
        }, 
        {
            "word" : "怎样",
            "weight" : 0.183103748050487
        }, 
        {
            "word" : "购置的车辆",
            "weight" : 0.595415748267281
        }, 
        {
            "word" : "新购置",
            "weight" : 0.551929302724666
        }
    ]
}

原始mongodb语句:
[“缴纳”,“车船税”]是自定义的集合,可根据业务需求改变。
这里可以是数据中的数据。如换成$items就是查询数据中items集合与mapDarkTitle.word集合交集,这里肯定是空的,因为这两个数据在数据中没有交集。

db.getCollection('hb_xxx_xxx').aggregate([   
{ $project: { title: 1,commonToBoth: { $setIntersection: [ ["缴纳","车船税"], "$mapDarkTitle.word" ] } }},
{ $project: { title: 1,commonToBoth:1,commonToBothSize: { $size: "$commonToBoth" } }},
{$sort: {"commonToBothSize": -1}},
{$limit: 30},
]);

查询结果:
在这里插入图片描述

spring-boot-date(mongoTemplate)仿mongodb代码实现
注:测试代码没有规范化,阅读应该还是没问题的。
这里的words是个list里面存放的便是“缴纳”,“车船税”

 List<Document> dbObjects = new ArrayList<>();

        Document limit = new Document();
        Document project = new Document();
        Document condition = new Document();
        Document project2 = new Document();
        Document condition2 = new Document();
        Document sort = new Document();

        condition.put("title", 1);
        List<Object> listIntersects = new ArrayList<>();
        listIntersects.add(words);
        listIntersects.add("$mapDarkTitle.word");
        condition.put("commonToBoth", new Document("$setIntersection", listIntersects));
        project.put("$project", condition);

        condition2.put("title", 1);
        condition2.put("commonToBoth", 1);
        condition2.put("commonToBothSize", new Document("$size", "$commonToBoth"));
        project2.put("$project", condition2);

        sort.put("$sort", new Document("commonToBothSize", -1));
        limit.put("$limit", 20);

        dbObjects.add(project);
        dbObjects.add(project2);
        dbObjects.add(sort);
        dbObjects.add(limit);

        AggregateIterable<Document> re = mongoTemplate.getCollection("hb_xxx_xxx")
                                                      .aggregate(dbObjects);

        List<Document> listDocument = new ArrayList<>();
        for (Iterator<Document> it = re.iterator(); it.hasNext();) {
            Document dbo = it.next();
            listDocument.add(dbo);
        }

mongoTemplate可以用另一种方式实现上述操作,但本人经过尝试未果,猜测是受$影响,无法对自定义的集合进行传入。所有用了上述这种直接将原生语句转化。

作者实习萌新一枚,还在疯狂采坑过程中,如有错误地方请指出。

本需求来自 http://www.helper12366.com/taxAnswer 智能问答优化过程

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值