基于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});