springboot版本
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
org.springframework.boot
spring-boot-starter-data-mongodb
1、基本查询
新建对应mong表中的实体类:
/**
* @Description:测试实例
* @Author:wb
*/
@Document(collection = "yylive_new_web")//对应数据的表名
@Data
@NoArgsConstructor
public class TestModel {
private String _id;//主键id
@Field("type")//对应表中的字段信息
private String type;
@Field("total_consume")
private Double dayConsume;//总星光值/币
@Field("total_lives")
private Long dayLives;//总房间数
@Field("date")
private String date;
@Transient//设置忽略的字段
private String ignore;
}
dao层:
/**
* @Description:测试
* @Author:wb
*/
@Component
public class FunctionRepository {
@Autowired
private MongoTemplate mongoTemplate;
/*
* 查询
*/
public void select(){
Query query = new Query();
query.addCriteria(Criteria.where("type").is("day"));
query.addCriteria(Criteria.where("date").gte("2018-01-01").lte("2018-10-01"));
query.limit(10);
query.skip(5);
query.with(new Sort(Sort.Direction.ASC, "date"));
List testModels = mongoTemplate.find(query, TestModel.class);
}
对应mong的语法:
db.getCollection('yylive_new_web').find({'type':'day','date':{'$gt':'2018-01-01','$lt':'2018-10-01'}}).limit(10).skip(5).sort({'date':1})
2、更新、插入
/*
* 更新
*/
public void update(){
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("57eb870e2954a36d823bcbd6")));
Update update = new Update().set("type", "month");
UpdateResult updateResult = mongoTemplate.updateFirst(query, update, TestModel.class);
long modifiedCount = updateResult.getModifiedCount();//已完成修改的条数,也就是修改结果
long matchedCount = updateResult.getMatchedCount();//预完成修改的条数
}
/*
* 插入
*/
public void insert(){
TestModel testModel = new TestModel();
testModel.setDate("2018-10-10");
mongoTemplate.insert(testModel);
String objectId = testModel.get_id();
}
对应mong的语法:
db.getCollection('user_test').update({'_id':ObjectId('57eb870e2954a36d823bcbd6')},{'$set':{'type':'year'}})
db.getCollection('user_test').insert({'date':'2018-10-10', .....})
这种是比较常用的操作方式,唯一比较麻烦的一点是需要指定实体类的表名,字段对应的数据类型要求很严格,list和map一定区分好。
3、使用spring框架插入数据时,带有“_class”项的解决方法:
/**
* @Description:mong配置,去除插入mong数据时框架自带的_class字段
* @Author:wb
*/
@Configuration
public class MongoConfig implements ApplicationListener {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
MongoConverter converter = mongoTemplate.getConverter();
if (converter.getTypeMapper().isTypeKey("_class")) {
((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));
}
}
}
1、java获取mongodb接连实例
//手动获取
MongoClientURI uri = new MongoClientURI("mongodb://ssymm:#EDCvbNHY^[email protected]:27018/ssymmetry_db");
MongoClient mongoClient = new MongoClient(uri);
MongoDatabase mongodb = mongoClient.getDatabase("ssymmetry_db");
MongoCollection collection = mongodb.getCollection("user_test");
//springboot
MongoCollection collection = mongoTemplate.getCollection("user_test");
2、数据筛选的两种方式
Bson bson1 = Filters.exists("unionid", true);
Bson bson2 = Filters.eq("username", "[email protected]");
Bson bson3 = Filters.and(bson1, bson2);
FindIterable documents = collection.find(bson3);
for (Document document : documents) {
System.out.println(document);
}
Document params = new Document();
params.put("unionid", new Document("$exists", true));
params.put("username", "[email protected]");
//params.append("type", "year");
FindIterable documents = collection.find(params);
for (Document document : documents) {
System.out.println(document);
}
对应mong的语法:
db.getCollection('user_test').find({'unionid':{'$exists':true}, 'username':'[email protected]'})
这两种数据查询的方式结果是一样的,但是个人感觉Document的方式会更为常用,Bson查询的方式比较死板,另外一些更新的操作使用Document会更方便。
3、更新、插入
1)$set方式,set的机制是,如果存在该字段则修改该字段的值,不存在则新添加一个字段:
collection.updateMany(new Document(), new Document("$set", new Document("age", 25)));
collection.updateOne(new Document("username", "[email protected]"), new Document("$set", new Document("age", 23)));
对应mong的语法:
db.getCollection('user_test').update({},{'$set':{'age':NumberInt(20)}});
db.getCollection('user_test').update({'username':'[email protected]'},{'$set':{'age':NumberInt(20)}})
2)$inc方式,inc机制和set一样,但是它只针对数值类型的数据有效,并且是一种自增机制:
collection.updateOne(new Document(), new Document("$inc", new Document("age", 1)));
对应mong的语法:
db.getCollection('user_test').update({},{'$inc':{'age':NumberInt(1)}})
3)其他更新操作符号:
4)插入:
collection.insertOne(new Document("name", "test").append("age", 20).append("address", "北京"));
1、$project:改变文档的输出结构,0不显示,1显示
List list = new ArrayList();
BasicDBObject params = new BasicDBObject();
params.put("_id", 0);
params.put("name", "$username");
params.put("age", 1);
BasicDBObject project = new BasicDBObject("$project", params);
list.add(project);
AggregateIterable aggregate = collection.aggregate(list);
for (Document document : aggregate) {
System.out.println(document);
}
或者
List list = new ArrayList();
Document params = new Document("_id", 0).append("name", "$username").append("age", 1);
Document project = new Document("$project", params);
list.add(project);
AggregateIterable aggregate = collection.aggregate(list);
for (Document document : aggregate) {
System.out.println(document);
}
这两种方式都可以,就像Bson和Document一样,具体区别没有研究,可能有版本的关系,但是推荐使用Document,任何时候都不会出错。
对应mong的语法:
db.getCollection('user_test').aggregate([{
'$project':{
'_id':0,
'name':'$username',//重新设定返回的字段名称
'age':1
}
}])
2、$match过滤数据
List list = new ArrayList();
Document param = new Document();
param.put("age", new Document("$gt", 20).append("$lt", 50));
Pattern pattern = Pattern.compile("^.*ssymmetry.*$");
param.put("username", pattern);
Document match = new Document("$match", param);
list.add(match);
AggregateIterable aggregate = collection.aggregate(list);
for (Document document : aggregate) {
System.out.println(document);
}
对应mong的语法:
db.getCollection('user_test').aggregate([{
'$match':{
'username':/ssymmetry/,
'age':{'$gt':20,'$lt':50}
}
}])
3、限制结果数量,跳过指定数量,排序
List list = new ArrayList();
Document skip = new Document("$skip", 1);
Document limit = new Document("$limit", 2);
Document sort = new Document("$sort", new Document("age", 1));
list.add(skip);
list.add(limit);
list.add(sort);
AggregateIterable aggregate = collection.aggregate(list);
for (Document document : aggregate) {
System.out.println(document);
}
对应mong的语法:
db.getCollection('user_test').aggregate([
{'$skip':1},
{'$limit':2},
{'$sort':{'age':1}}
])
4、$unwind对list集合进行拆分
List list = new ArrayList();
Document unwind = new Document("$unwind", "$top_lives_consume");
Document match = new Document("$match", new Document("top_lives_consume", 17662500.0));
list.add(unwind);
list.add(match);
AggregateIterable aggregate = collection.aggregate(list);
for (Document document : aggregate) {
System.out.println(document);
}
对应mong的语法:
db.getCollection('yylive_new_web').aggregate([
{$unwind:'$top_lives_consume'},
{$match:{'top_lives_consume':17662500.0}}
])
5、$group分组,_id是必须项,_id字段内存放的是要分组的字段,可以达到去重的目的
List list = new ArrayList();
Document ids = new Document("username", "$username").append("password", "$password");
Document params = new Document("_id", ids).append("sum", new Document("$sum", 1));
Document group = new Document("$group", params);
list.add(group);
AggregateIterable aggregate = collection.aggregate(list);
for (Document document : aggregate) {
System.out.println(document);
}
对应mong的语法:
db.getCollection('user_test').aggregate([{
'$group':{
'_id':{
'username':'$username',
'password':'$password'
},
'sum':{'$sum':1}
}
}])
6、复杂查询
查询逻辑:查询stock_code是三个id中的一个,并且有日期范围,每个id的结果有很多条,对结果以stock_code进行分组,分组计算每组的情绪均值和统计结果数量,再对结果进行排序后重新更改字段输出
List list = new ArrayList();
List idList = new ArrayList();
idList.add("000671");
idList.add("002397");
Document matchParam = new Document("stock_code", new Document("$in", idList))
.append("date", new Document("$gt", "2018-01-01").append("$lt", "2018-10-01"));
Document match = new Document("$match", matchParam);
Document groupParam = new Document("_id", new Document("stockCode", "$stock_code").append("stockName", "$stock_name"))
.append("avgSentiment", new Document("$avg", "$sentiment"))
.append("sum", new Document("$sum", 1));
Document group = new Document("$group", groupParam);
Document projectParam = new Document("_id", 0)
.append("stockCode", "$_id.stockCode")
.append("stockName", "$_id.stockName")
.append("avgSentiment", "$avgSentiment")
.append("count", "$sum");
Document project = new Document("$project", projectParam);
Document sortParam = new Document("stockCode", 1);
Document sort = new Document("$sort", sortParam);
list.add(match);
list.add(group);
list.add(project);
list.add(sort);
AggregateIterable aggregate = collection.aggregate(list);
for (Document document : aggregate) {
System.out.println(document);
}
对应mong的语法:
db.getCollection('xueqiu_sentiment_index_hourly_collection').aggregate([
{'$match':{
'stock_code':{'$in':['000671','002397']},
'date':{'$gt':'2018-01-01','$lt':'2018-10-01'}
}
},
{'$group':{
'_id':{
'stockCode':'$stock_code',
'stockName':'$stock_name'
},
'avgSentiment':{'$avg':'$sentiment'},
'sum':{'$sum':1}
}
},
{'$project':{
'_id':0,
'stockCode':'$_id.stockCode',
'stockName':'$_id.stockName',
'avgSentiment':'$avgSentiment',
'count':'$sum',
}
},
{'$sort':{
'stockCode':1
}
}
])
1、模糊匹配(相当于mysql:like “%ssymmetry%”)
//java
Pattern.compile("^.*ssymmetry.*$", Pattern.CASE_INSENSITIVE);
//mong正则写法
'username':{'$regex':/ssymmetry/}
//mong简单写法
'username':/ssymmetry/
2、左匹配(相当于mysql:like “ssymmetry%”)
//java
Pattern.compile("^ssymmetry.*$");
//mong正则写法
'username':{'$regex':/^ssymmetry/}
//mong简单写法
'username':/^ssymmetry/
2、右匹配(相当于mysql:like “%ssymmetry”)
//java
Pattern.compile("^.*ssymmetry$");
//mong正则写法
'username':{'$regex':/ssymmetry$/}
//mong简单写法
'username':/ssymmetry$/
3、忽略大小写
//java
Pattern.compile("^.*ssymmetry.*$", Pattern.CASE_INSENSITIVE);
//mong正则写法
'username':{'$regex':/ssymmetry/,'$options':'i'}
'username':{'$regex':/ssymmetry/i}
//mong简单写法
'username':/ssymmetry/i