您的位置:首页 > 数据库 > Mongodb

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

2018-12-05 16:38 2261 查看

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

需求:根据自定义数据集合与数据库中指定集合的交集,
得到一个交集集合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 智能问答优化过程

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: