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

基于springboot构建
引入依赖

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

配置连接参数

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

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

使用

    @Autowired
    MongoTemplate mongoTemplate;

常用的方法解释

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

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

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

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

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

查询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");

联查的概念以及写法

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

此处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

实际的联查写法

        //多表关联的条件声明
        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);
        }

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

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

分组聚合排序查询
例现有一竞价排名表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

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}
)

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为升序,-1为降序。unique设置为唯一索引

db.offer.createIndex({"uid": 1,"time": 1},{"unique": true});
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值