英文专业的网站设计,网站开发用的是什么语言,手机网页在线,全网营销平台nosql对我来说#xff0c;就是用它的变动列#xff0c;如果列是固定的#xff0c;我为什么不用mysql这种关系型数据库呢#xff1f;
所以#xff0c;现在网上搜出来的大部分#xff0c;用实体类去接的做法#xff0c;并不适合我的需求。
所以#xff0c;整理记录一下…nosql对我来说就是用它的变动列如果列是固定的我为什么不用mysql这种关系型数据库呢
所以现在网上搜出来的大部分用实体类去接的做法并不适合我的需求。
所以整理记录一下我收集到的springboot自由使用mongo的信息。
目录
前置
依赖引入
配置
代码引入
使用
插入
单行插入
批量插入
查询
查询全部无条件
条件查询
排序 DBObject更加自由的查询
聚合
某些列有值并且只返回选中的列并且聚合
其他工具包像客户端一样写查询
mongodb的java驱动MongoClient 前置
依赖引入
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-mongodb/artifactId
/dependency
版本就根据自己的spring版本来好了不需要额外加
配置
spring.data.mongodb.urimongodb://localhost:27017/myTest
我用的本地版本的mongo没配用户名密码如果配了就需要加下。
本地mongodb的安装我使用了菜鸟 MongoDB 安装介绍并安装了mongoDB compass客户端用来直连查看mongodb里的数据库数据
代码引入
Resource private MongoTemplate template;
上述配置完成后直接依赖注入就可以使用了
使用
插入
单行插入
template.insert(singleObject, multi_1242);
上述代码中
singleObject 为 json字符串 {_id: 3, 1: 1.1, 2: 2.1, amount: 2.1}
multi_1242 为集合名称我的需求是不同的集合里面document的键名是会完全不同的
批量插入
boolean product template.collectionExists(multi_1242);if (!product) {template.createCollection(multi_1242);}Gson gson new Gson();JsonObject jsonObject new JsonObject();jsonObject.addProperty(_id, 1);jsonObject.addProperty(1, 1.1);jsonObject.addProperty(2, 2.2);jsonObject.addProperty(amount, 10.12);// template.save(gson.toJson(jsonObject), multi_1242);JsonObject jsonObject1 new JsonObject();jsonObject1.addProperty(_id, 2);jsonObject1.addProperty(1, 1.2);jsonObject.addProperty(2, 2.2);jsonObject1.addProperty(3, 3.1);jsonObject1.addProperty(amount, 1.13);// template.save(gson.toJson(jsonObject1), multi_1242);ListString list new ArrayList();list.add(gson.toJson(jsonObject));list.add(gson.toJson(jsonObject1));template.insert(list, multi_1242);
这里我使用了google的Json化的工具包我没有使用ali的fastjson是因为它的JSON对象转JSON字符串曾经坑过我它会把一些特殊字符转换成别的字符
dependencygroupIdcom.google.code.gson/groupIdartifactIdgson/artifactIdversion2.10.1/version
/dependency
import com.google.gson.Gson;
import com.google.gson.JsonObject;
上述动作完成插入后mongo那边显示的结果为 从上述的实验可以得出几个结论
1、springboot插入mongo的话也是用json字符串去插入的我曾经试过直接用jsonObject类型去插入document查出来会有很多不需要的字段都被插进去了这并不是我想要的所以你想插入什么样子就组装成什么样子后json字符串后再传入进去。下图为错误示范。 2、_id这个键是默认的主键名称如果你想控制主键多少可以设置后再进行插入
查询
查询全部无条件
Query query new Query();
ListString list template.find(query, String.class, multi_1242);//查看测试结果
LoggerUtils.info(size is list.size());
for (int i 0; i list.size(); i) {//使用了封装类打印了一下查出来的结果LoggerUtils.info(i is list.get(i));
}
不需要传入查询条件传个空的query进去就行了
下图为输出结果 条件查询
2个and的查询条件
Query query new Query();
Criteria criteria new Criteria();
criteria.where(1).is(1.1);
criteria.and(2).is(2.1);
query.addCriteria(criteria);
ListString list template.find(query, String.class, multi_1242);
查询结果 如果有的document缺少查询条件里的一些键呢结果是如何呢 然后我增加了一个查询条件
Query query new Query();
Criteria criteria new Criteria();
criteria.where(1).is(1.1);
criteria.and(2).is(2.1);
//增加一条查询条件
criteria.and(3).is(3.1);
query.addCriteria(criteria);
ListString list template.find(query, String.class, multi_1242); 结果是没有查出来如果写在where里明确某个键某个值的话那么查出来的document必然是有该键的。
但是order却不一定为此我多插了一行{_id: 4, 1: 1.1, 2: 2.1,3: 3.1, amount: 2.1}
排序
Query query new Query();
Criteria criteria new Criteria();
criteria.where(1).is(1.1);
criteria.and(2).is(2.1);
query.addCriteria(criteria);
//增加一条排序条件
query.with(Sort.by(3));
ListString list template.find(query, String.class, multi_1242);
结果 可以看到order依赖的属性不存在也是可以被查出来的并且正常排序还排在前面 DBObject更加自由的查询
上述用这个Query类构造还是束手束脚的不过我又查到了跟客户端类似的方法 DBObject obj new BasicDBObject();
obj.put(1, 1.1);
obj.put(2, 2.1);
Query query new BasicQuery(obj.toString());
ListString list template.find(query, String.class, multi_1242);
仿照着写查询结果是ok的 如果是复杂的查询可以自己用DBObjectBasicDBList构造嵌套起来
聚合
某些列有值并且只返回选中的列并且聚合
如果是客户端的话可以先过滤出来后再进行聚合
例如我想找到“1”列“2”列有值并且根据这两列进行合并的并且返回的结果只包含这2列作为_id意味着如果有1.12.13.1和1.12.1的组合将会合并到一起
db.multi_1242.aggregate([
#先过滤一波需要的数据
{$match:
{
1:{$exists:true},
2:{$exists:true}
}
},
#然后进行合并_id使用要合并的字段组成
# mytotal这个键是我随便起的就是group后面跟的对象就是将会输出的数据格式
{$group:
{
_id:{1:$1,2:$2},
mytotal:{$sum:$amount}
}
}
])
原始数据如图 查询后的结果如下 可以看到我的_id设置的只有“1”列和“2”列所以合并也是根据我的要求来合的。
如果我的_id加入了“3”列那么有的document行有3这个键值有的没有又该如何
查询如下 可以发现有“3” 列的就有没有“3”列的就没有。
客户端是这样那么如何在项目中使用聚合来查询
Aggregation aggregation Aggregation.newAggregation(Aggregation.match(new Criteria().where(1).is(obj1).and(2).is(obj1)),Aggregation.group(1, 2).sum(amount).as(mytotal));
AggregationResults results template.aggregate(aggregation, multi_1242, String.class);
ListString mappedResults results.getMappedResults();
打印得到的结果 这个group查多组合需要传 Fields
import org.springframework.data.mongodb.core.aggregation.Fields;DBObject obj1 new BasicDBObject();
obj1.put($exists, true);Fields fields Fields.fields(1);
fields fields.and(2);
fields fields.and(3);
Aggregation aggregation Aggregation.newAggregation(Aggregation.match(new Criteria().where(1).is(obj1).and(2).is(obj1)),Aggregation.group(fields).sum(amount).as(mytotal));
AggregationResults results template.aggregate(aggregation, multi_1242, String.class);
ListString mappedResults results.getMappedResults();
查询结果 这个Fields还真是难造看了下源码才知道怎么造出来。
然后如果不想调用各种聚合函数比如sumcount也是可以的。
比如我把上面的聚合查询改为这样。
Aggregation aggregation Aggregation.newAggregation(Aggregation.match(new Criteria().where(1).is(obj1).and(2).is(obj1)),Aggregation.group(fields));
结果如下 只会查出聚合的键这也是我需要的内容
其他工具包像客户端一样写查询
mongodb的java驱动MongoClient
mongoClient的参考文章
其中的这种写法我是比较赞赏的因为都是字符串拼接很自由引用一下。
Document match Document.parse({$match:{$or:[{\组织机构代码\:\ id \}, {\单位名称\:\ id \}]}});
Document unwind Document.parse({$unwind:\$公司人员\});
Document group Document.parse({$group : {_id : \$公司人员. arrayFiled \, count : {$sum : 1}}});ListDocument conditions new ArrayList();
conditions.add(match);
conditions.add(unwind);
conditions.add(group);ListDocument result new ArrayList();
AggregateIterableDocument resultSet this.collection.aggregate(conditions);
try (MongoCursorDocument cursor resultSet.iterator()) {while (cursor.hasNext()) {Document item_doc cursor.next();result.add(item_doc);}
}
Bson的话两种工具包好像都可以进行使用我这边就不赘述了。