当前位置:   article > 正文

java操作mongodb以及多表/集合联查_mongotemplate多表联合查询

mongotemplate多表联合查询

基于springboot构建
引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4

配置连接参数

spring.data.mongodb.host=192.168.211.147
spring.data.mongodb.port=27017
spring.data.mongodb.username=mongoadmin
spring.data.mongodb.password=secret
spring.data.mongodb.database=onedb
#从哪个库查找上面的用户
spring.data.mongodb.authentication-database=admin
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

authentication-database:mongod的用户信息并非集中保存在一个地方,创建的时候使用/指定了哪个库,用户信息就保存在那个库,所以需要指定查找此用户的库,默认为admin

使用

    @Autowired
    MongoTemplate mongoTemplate;
  • 1
  • 2

常用的方法解释

 * mongoTemplate.insert 常规的insert
 * mongoTemplate.save   等价于insert update for key
  • 1
  • 2

 * mongoTemplate.findAndRemove  按照条件查询删除一条
 * mongoTemplate.findAllAndRemove 按照条件查询删除所有,实体类中需要包括主键
 * mongoTemplate.remove 根据查询条件删除所有,或者传入实体类根据主键删除一条
  • 1
  • 2
  • 3

 * mongoTemplate.findAndModify      查找满足条件的,按照update规则修改一条
 * mongoTemplate.findAndReplace     查找满足条件的,整个替换为新的/相当于删除旧的再插入新的
 * mongoTemplate.updateFirst        根据条件修改一条
 * mongoTemplate.updateMulti        根据条件全部修改
 * <p>
 * <p>update集合测试以jsonArry为例
 * update.set       将值修改为一个新的值
 * update.addToSet  向原来集合中追加一个值,值存在则不操作
 * update.push      将新的集合全部追加到指定集合,新旧集合类型需要相同,不会去重
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

 * mongoTemplate.findAll        查找所有数据
 * mongoTemplate.find           根据条件查询所有满足的数据
 * mongoTemplate.findOne        根据条件查询一条满足的数据
 * mongoTemplate.findById       根据主键查询一条
 * mongoTemplate.findDistinct   根据查询条件去重查询,需要指定去重的列,返回的值也只为此列
  • 1
  • 2
  • 3
  • 4
  • 5

简单的查询和修改条件编写

查询table1中所有age=10的数据,将age修改为99并向array中追加一个新值

        Query query = Query.query(Criteria.where("age").is(10));
//        query1写法等价于上面query
//        Query query1 = new Query();
//        query1.addCriteria(Criteria.where("age").is(10));

        Update update = Update.update("age", 99);
//        update1写法等价于上面update1
//        Update update1 = new Update();
//        update1.set("age",99);


        JSONArray ary = new JSONArray();
        ary.add("test");
        update.push("array", ary);
        
        mongoTemplate.updateMulti(query, update, "table_1");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

联查的概念以及写法

mongod中没有表的概念,方便理解任然称集合为表。实际上集合更贴近于redis的某个库,只不过redis固定了库只能用数字选,而mongod可以自己命名

此处假定有四张表a,b,c,d,其中的字段关联关系如图
在这里插入图片描述
联查sql的话大概可以这么写

select * from a,b,c,d
where a.id_1=b.id_1
and b.id_2=c.id_2
and c.id_3=d.id_3
  • 1
  • 2
  • 3
  • 4

此处sql使用的是‘where =’为一个伪概念,mongod的联查实际上应是join
sql的where =多表查询没有主从表概念,而mongod的联查是需要指定一个主表然后关联副表查询,如果在mongod中想要实现上述效果,需要再新建一张映射表TAB_MAP,关联结构为
在这里插入图片描述
因为关联查询只能从一张表发出关联,所以map为主表,查询的概念写法为

select * from a,b,c,d,map
where map.id1 = a.id1
and map.id2 = b.id2
and map.id2 = c.id2
and map.id3 = d.id3
  • 1
  • 2
  • 3
  • 4
  • 5

实际的联查写法

        //多表关联的条件声明
        LookupOperation cusAndInfoLookup = LookupOperation.newLookup().
                from("adrs").//1.副表表名字
                localField("_id").//2.主表的关联字段
                foreignField("adrsId").//3.副表的关联字段
                as("adrs");//4.建议和1一致,结果的别名
        //关联多张表就写多个
//        LookupOperation cusAndInfoLookup1 = LookupOperation.newLookup().
//                from("adrs").
//                localField("_id").
//                foreignField("adrsId").
//                as("adrs");


        //多表的关联条件,查询条件均传入到此
        Aggregation aggregation = Aggregation.newAggregation(
                cusAndInfoLookup,
//                cusAndInfoLookup1,
//                Aggregation.match(Criteria.where("_id").lte(2)),
                  //5.此作用处下文解释
//                Aggregation.unwind("adrs"),
                //筛选条件,筛选主表的字段直接写,副表则是'别名.字段名'
                Aggregation.match(Criteria.where("adrs.adrsId").is(1))
        );

                                                                                  //5.此处填写主表名称
        AggregationResults<JSONObject> results = mongoTemplate.aggregate(aggregation, "tab_map", JSONObject.class);
        List<JSONObject> objectList = results.getMappedResults();
        for (JSONObject json : objectList) {
            System.out.println(json);
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

unwind的作用,默认关联查询出现多个关联值时,结果会以array返回,例如一个用户有多个收货地址,则会返回

{"id":"1","adrs":[{adrs1},{adrs2}]}
unwind("adrs")返回数据成为常见的sql返回多条
{"id":"1","adrs":{adrs1}}
{"id":"1","adrs":{adrs2}}
  • 1
  • 2
  • 3
  • 4

分组聚合排序查询
例现有一竞价排名表offer,其中有状态sts,p报价,q数量/时长

现要对有效的报价进行筛选。目的是按照最低报价统计有几家服务商报价,因为不同报价商存在报价相同但时长不同的情况,表明共可以使用多久。分页查询,当前显示第2页

统计结果p为价格,count为此价格的报价商总数量,sq为总报价数量
mysql写法为

select p,count(p) `count`,sum(q) sq from offer where sts=1 group by p order by p asc limit 10,10
  • 1

mongod写法以及解释

db.offer.aggregate(
//$match为关键字,等价sql中where
{'$match': {'sts': 1}},

//$group为关键字,联合后面的_id键值对,等价于sql中 group by p
//$group的参数_id为关键字,不可修改。p为列名需要加$
//count、sq为自己取的列名,$sum为关键字,等价于sql中sum()
//{'$sum': 1}表示每行计数1,效力同等于sql中count()。{'$sum': '$q'}等价于sql中sum(q)
{'$group': {'_id': '$p','count': {'$sum': 1},'sq': {'$sum': '$q'}}},

//$sort为关键字,等价于sql中order by,值1表示asc,-1表示desc
{'$sort': {'_id': 1}},
//$skip,$limit均为关键字,skip跳过多少条,limit取多少条
{'$skip': 10},
{'$limit': 10}
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

java写法

        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("sts").is(1)),
                Aggregation.group("$p").count().as("count").sum("q").as("sq"),
                Aggregation.sort(Sort.by("_id").ascending()),
                Aggregation.skip(10L),
                Aggregation.limit(10L)
        );


        AggregationResults<JSONObject> results = mongoTemplate.aggregate(aggregation, "offer", JSONObject.class);
        List<JSONObject> list = results.getMappedResults();
        for (JSONObject json : list) {
            System.out.println(json);
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

创建索引
1为升序,-1为降序。unique设置为唯一索引

db.offer.createIndex({"uid": 1,"time": 1},{"unique": true});
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/56052
推荐阅读
相关标签
  

闽ICP备14008679号