简单+进阶

  • 简单
  • 准备:
  • 查询:
  • 删除:
  • 增加:
  • 修改:
  • 思路
  • 进阶:
  • 查询(指定字段过滤)
  • 修改(多层数组精确修改)
  • 讨论
  • 总结



注:本文只讲在java中的使用,并且只简单讲一下本人在开发中遇到的一部分 并不完全概括 在cmd中的请自行查看其他博主.

简单

准备:

想用它就得引入它:

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


在service中
    @Resource
    private MongoTemplate mongoTemplate;
    所有的方法都在mongoTemplate中

查询:

Criteria criteria = new Criteria();
       
        String name = jsonObject.getString("name");
        //模糊查询
        if(name != null){
            criteria.and("name").regex(".*?" + name + ".*?");
        }

        //排序
        Query query = new Query(criteria).with(Sort.by("createDate"));
        //开启分页
        mongoUtil.start(page, limit, query);
        //获取条数
        long count = mongoTemplate.count(query, Template.class);
        //分页数据
        PageHelper<Template> pageHelper = mongoUtil.pageHelper(count, mongoTemplate.find(query, Template.class));

删除:

//先查询出来数据 这里的is(id)可以改成in(ids) 即为批量删除
 Query query = new Query(Criteria.where("dataId").is(id));
 //再根据查询删除       
 return mongoTemplate.remove(query, Question.class);

增加:

实体类 newTemplate = new 实体类(字段1,字段2,...字段last);
//可以不需要先在数据库中创建,调用insert方法时 没有会自动创建
mongoTemplate.insert(newTemplate, "文档名即表名");

修改:

Query query = new Query(Criteria.where("_id").is(id));
  实体类 实体 = mongoTemplate.findOne(query, 实体类.class);
  //不存在数据就不要往下走了
  if(实体  == null){
     return 该数据为空或已被删除;
   }
   Update update = new Update();
   update.set("title", jsonObject.getString("title"));
   //最后一次修改时间
   update.set("updateDate", Date());
   mongoTemplate.updateFirst(query, update, 实体类.class);

思路

Query query = new Query() 相当于mysql的select
Criteria criteria = new Criteria();里的criteria 相当于where后的条件
实体类相当于表名
上面的理解就相当于select * from table where xxxx
MongoDb的增删改查都要调用Query query = new Query()

进阶:

上面的有手就行,下面是稍微复杂点的

查询(指定字段过滤)

如果不指定的话 每次查询其实都是select * ,一堆数据占用资源.实际上你只需要某个或者某些字段


 Query query = new Query(Criteria.where("questId").is(quId));

// query.fields().include("_id","quesTitle","createDate"); //包含该字段
  query.fields().exclude("questions");//不包含该字段
   实体类 实体= mongoTemplate.findOne(query, 实体类.class);

这个过滤我找了好久: 讲实话 抄来抄去的没有能用的就这个可以

参照: MongoTemplate查询返回指定字段

java mongoTemplate 是否存在 存在跟新 mongotemplate update_实体类

java mongoTemplate 是否存在 存在跟新 mongotemplate update_数据_02

java mongoTemplate 是否存在 存在跟新 mongotemplate update_java_03


java mongoTemplate 是否存在 存在跟新 mongotemplate update_数据_04


java mongoTemplate 是否存在 存在跟新 mongotemplate update_字段_05


java mongoTemplate 是否存在 存在跟新 mongotemplate update_字段_06

亲测有效 不过以上方法只支持第一层过滤,就是你文档的第一层,如果你想过滤字段的数组的某个对象 我没做到,如果你做到了,教教我 求求了

比如以下:

第一层 
即:quesTitle,endDate,count,questions,createDate,status,startDate
都可以过滤掉或者指定显示,但是questions中的total,options过滤不掉
questions中的options中的opId,sum,text更过滤不掉.
有会的 跪求你教我

{
	"quesTitle": "这是一个测试问卷",
	"endDate": "2021-08-30T17:21:21.247+08:00",
	"count": 19,
	"questions": [
		{
			"total": 2,
			"options": [
				{
					"opId": "1427545472754651136",
					"sum": 2,
					"text": "男"
				}
			],
			"title": "问题1",
			"quesId": "1419934979261075457"
		},
		{
			"total": 3,
			"options": [
				{
					"opId": "142754547275465116",
					"sum": 2,
					"text": "女"
				},
				{
					"opId": "1428872",
					"sum": 1,
					"text": "未知"
				}
			],
			"title": "您的性别",
			"quesId": "1430722700409704450"
		},
		{
			"total": 4,
			"options": [
				{
					"opId": "1432600351034445824",
					"sum": 2,
					"text": "0-2"
				},
				{
					"opId": "1432600351034445825",
					"sum": 1,
					"text": "2-5"
				},
				{
					"opId": "1432600351034445826",
					"sum": 1,
					"text": "5-10"
				},
				{
					"opId": "1432600351034445827",
					"sum": 1,
					"text": "10+"
				}
			],
			"title": "你的工作年限",
			"quesId": "1432600351034445828"
		},
		{
			"total": 4,
			"options": [
				{
					"opId": "1432600445817327616",
					"sum": 2,
					"text": "篮球"
				},
				{
					"opId": "1432600445817327617",
					"sum": 1,
					"text": "打游戏"
				},
				{
					"opId": "1432600445817327618",
					"sum": 1,
					"text": "睡觉"
				}
			],
			"title": "您的兴趣爱好",
			"quesId": "1432600445817327619"
		},
		{
			"total": 6,
			"options": [
				{
					"opId": "14288721111",
					"sum": 6,
					"text": "test"
				}
			],
			"title": "问题3",
			"quesId": "12345678"
		}
	],
	"startDate": "2021-08-30T17:21:21.247+08:00",
	"status": 1,
	"createDate": "Mon Aug 30 17:21:21 CST 2021"
}

修改(多层数组精确修改)

比如以上文档 你可以修改questions下的指定quesId的同级参数如title,total
Query qu = new Query(Criteria.where("_id").is(id).and("questions.quesId").is(quesId));
	Update update = new Update();
    update.set("options.$.title", title);
    mongoTemplate.updateFirst(qu, update, 实体类.class);
修改第二层 这个没有问题

好 然后你又想修改第三层 即:questions下的options下的某个参数如sum,text
或许你想根据上面的写法
Query qu = new Query(Criteria.where("_id").is(id).and("questions.quesId").is(quesId).and("questions.options.opId").is(opId));
	Update update = new Update();
    update.set("options.$.options.text", text);
    mongoTemplate.updateFirst(qu, update, 实体类.class);
    不好意思 这样的写法 你只能修改questions[0].options[0]
    如果你直接拿第一条数据测没问题了 就觉得没问题了提交代码上线 那你GG了.

	 要这样写:
	 int y = -1;
     int z = -1;
     for (int i1 = 0; i1 < list.size(); i1++) {
         if(quesId.equals(list.get(i1).getQuesId())){
             y = i1;
             List<Option> list1 = list.get(i1).getOptions();
             for(int i2 = 0; i2 < list1.size(); i2++){
                 if(opId.equals(list1.get(i2).getOpId())){
                     z = i2;
                     break;
                 }
             }
             break;
         }
     }
     if(y == -1 || z == -1){
         return "代码错误!出bug了";
     }
	 y
	 z
	 用来遍历确定要修改的questions中的第 y 个options,
	 第 y 个options中的第 z 个 sum 下标从0开始
     update.inc("questions."+y+".options."+z+".sum",1);
     update.set("questions."+y+".options."+z+".text",text);

讨论

当然以上方法本人迂回的思路 并不确定有没有更好的方法 毕竟遍历有消耗,多数据时很拉跨 如大佬有更好的方法 求你教我

总结

暂时先写这么多吧,其实怎么做都是围绕着数据,对数据的增删改查.
除了增删改查就是让程序更好的增删改查.