智能表单之mongoDB的使用

2018-03-01 11:12:48来源:oschina作者:huaizhe人点击

分享

在去年工作中遇见一个较为复杂的模块:智能表单。智能表单其实就问卷星一样的东西,由客户来根据需求设计表单内容样式,然后发布出去收集大家所填写的数据,最后进行统计分析,生成图表。


智能表单一开始遇见的困扰时数据库的设计。表单字段的不确定,对数据库要求的灵活性很大,所思之后解决方案主要有三:


1.根据用户设计的表单内容动态生成数据库表


2.使用一张非常多字段的,来容得下客户可能要求的最大字段个数。


3.内存数据库。


首先由于客户量不太小,第一种动态生成表的方式被否决了,怕数据库负担太大。第二种感觉有点太蠢了哈哈,然后就选择了第三种,由于需要进行统计分析,所有选择了mongDB来作为最终的解决方案。


接下来就总结工作中如何把mongoDB整合到spring mvc,因为这个模块其实做起来很多,只对与mongDB沾边的进行一些简单举例:


1.毋庸置疑,引坐标进pom.xml中,自行选择版本


org.springframework.dataspring-data-mongodb1.10.1.RELEASE org.mongodbmongo-java-driver3.2.2


2.配置mongoDB数据源


1.在applicationContext.xml中配置设置读取外部资源方便配置数据库信息ignore-unresolvable="true"如果已经存在配置外部资源的则需要设置此属性,否则默认只读取一个。


2.引入mongoBD配置在applicationContext中引入单独拿到一个文件中来。


3.编写spring-mongo.xml内容



//其实在智能表单中并不需要数据库字段的映射,所以这边引入只是为了当时学习一下,没有真正用到。


3.书写dao层,以方便使用,因为比较多,只简单列举几个,以便日后想起


列举一:


接口方法:


/** * 根据某一字段条件进行模糊查询 * @param field 字段名 * @param param 参数值 * @param cls 类型 * @return */ public List fuzzySearchByOneParam(String field, String param, Class cls);


实现方法:


@Overridepublic List fuzzySearchByOneParam(String field, String param, Class cls) { return getMongoTemplate().find(new Query(Criteria.where( field).regex(".*?//" +param+ ".*")), cls);}


列举二:


接口方法:


/** * 向集合众插入json格式文档 * @param jsonStr 要插入的json * @param collectionName 集合名称 */public void insertJSONObject(String jsonStr, String collectionName) throws Exception;


实现方法:


@Overridepublic void insertJSONObject(String jsonStr, String collectionName) throws Exception{ DBCollection collection = getMongoTemplate().getCollection(collectionName); BasicDBObject document = (BasicDBObject) JSON.parse(jsonStr); collection.insert(document);}


还有一个较为复杂的分组统计的方法,但是我个人的方法有点愚钝,希望有更好方式的大神能给予教导,提供更好的方法,在mongo管道这一块还有很多的欠缺。


列举三


接口方法:


/** * 通过输入的检索条件分组并查询匹配数据 * @param query 查询条件 * @param groupKey 分组字段 * @param operate 操作名称 * @param selectName 显示字段 * @param collectionName 文档名称 * @return * @throws Exception */public String findJsonObjectAndGroupByQuery(BasicDBObject query, String groupKey, Stringoperate, String selectName, String collectionName) throws Exception;


实现方法:


public String findJsonObjectAndGroupByQuery(BasicDBObject query, String groupKey, String operate, String selectName, String collectionName)throws Exception { DBCollection collection = getMongoTemplate().getCollection(collectionName); DBObject keys = new BasicDBObject(groupKey, 1); DBObject initial = new BasicDBObject("count", 0); initial.put("result", 0); String reduce = ""; String finalize = ""; if("avg".equals(operate)) { //求平均数reduce = "function(doc,out){out.count++; out.result = out.result + Number(doc." + selectName + ");}";finalize = "function(out){out.result = out.result / out.count; return out;}"; } else if("sum".equals(operate)) { //求总和reduce = "function(doc,out){out.count++; out.result = out.result + Number(doc." + selectName + ");}";finalize = "function(out){return out;}"; } else if("max".equals(operate)) { //求最大reduce = "function(doc,out){out.count++; if(out.result < Number(doc." + selectName + "))out.result = Number(doc." + selectName + ");}";finalize = "function(out){return out;}"; } else if("min".equals(operate)) { //求最小initial.put("result", Long.MAX_VALUE);reduce = "function(doc,out){out.count++; if(out.result > Number(doc." + selectName + "))out.result = Number(doc." + selectName + ");}";finalize = "function(out){if(out.result==" + Long.MAX_VALUE + ") {out.result = 0} return out;}"; } else if("count".equals(operate)) { //求总数reduce = "function(doc,out){out.count++;}";finalize = "function(out){out.result = out.count; return out;}"; } else {throw new Exception(); }BasicDBList dbList = (BasicDBList) collection.group(keys, query, initial, reduce, finalize); ListIterator listIterator = dbList.listIterator(); Gson gson = new Gson();List resultList = new ArrayList<>(); while(listIterator.hasNext()) {Map resultMap = gson.fromJson(String.valueOf(listIterator.next()), new TypeToken() {}.getType());resultList.add(resultMap); } return gson.toJson(resultList);}


mongDB很多命令行实现方式与js极为相似,所以我在实现分组的时候其实采用的是类似于js语言的实现方式。现在已记不清为什么不使用Aggregation管道操作来实现了。。。也记不太清遇到了什么难题,让我转而用这种方式,好像当时是因为数据类型的问题,无法进行正确的统计。


补充:最后瞎扯一下,如果使用mongoDB需要进行映射的操作,需要在pojo上声明注解@Document,这样你类中id就会与mongoDB中默认主键_id对应上,否则会被认为是一个新的字段,就这样啦啦。

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台