Spring data mongodb的内嵌数组的简单使用(一)

最近公司需要使用mongodb作为一个无知的我,学习了一下,翻阅了大量的教程,简单的就不说了。附个链接:

http://www.runoob.com/mongodb/mongodb-tutorial.html

关于内嵌对象,当时搞得头大。所以这里总结一下,做个笔记。

1、JavaBean对象

public class EventRead  implements Serializable {

    @ApiModelProperty("商户ID")
    @Indexed
    private String tenantId;

    @ApiModelProperty("用户id")
    @Indexed
    private Integer userId;

    @ApiModelProperty("通知类型和最后记录时间的对象List")
    private  List<EventReadTim> eventReadTimeList;

    @ApiModelProperty("通知类型和最后记录时间的对象")
    private  EventReadTim eventReadTime;

    @ApiModelProperty("最后记录时间")
    private Date lastDate;
}

注意:

@ApiModelProperty("最后记录时间")
private Date lastDate;

这个是因为我的个人需求,需要获取时间,在查询结果的时候直接取出来放到这里(其它地方直接用就可以了,减少相关代码)

@ApiModelProperty("通知类型和最后记录时间的对象")
private  EventReadTim eventReadTime;

这个是因为存入mongodb的时候如果使用list<EventReadTim> 在追加插入的时候会在插入一个数组,不是我想要的结果,或者直接用list.get(0)也是可以,但是觉得麻烦就单独弄出来一个。

2、存入mongodb代码

/**
 * 保存消息设置
 * @param
 */
public void upsetEventRead(EventRead eventRead,Integer type) {
	Criteria c = new Criteria().andOperator(Criteria.where("tenantId").is(eventRead.getTenantId()),Criteria.where("userId").is(eventRead.getUserId()));
	Query query = new Query().addCriteria(c);
	EventRead eventReadTem = this.mongoTemplate.findOne(query, EventRead.class, collectionName);
	if (eventReadTem==null){//没有相关记录,第一次添加
		List<EventReadTim> eventReadTimeList = new ArrayList();
		eventReadTimeList.add(eventRead.getEventReadTime());
		Update update = new Update().set("tenantId",eventRead.getTenantId()).set("userId",eventRead.getUserId()).set("eventReadTimeList",eventReadTimeList);
		Query query1 = new Query().addCriteria(c);
		mongoTemplate.upsert(query1, update, EventRead.class, collectionName);
	}else {
		//删除某一个元素
		Criteria c2 = new Criteria().andOperator(Criteria.where("tenantId").is(eventRead.getTenantId()),Criteria.where("userId").is(eventRead.getUserId()),Criteria.where("eventReadTimeList.type").is(type));
		Query query2 = new Query().addCriteria(c2);
		Update update = new Update().pull("eventReadTimeList",new BasicDBObject("type",type));
		mongoTemplate.updateFirst(query2, update, EventRead.class, collectionName);
		//重新追加元素
		Criteria c3 = new Criteria().andOperator(Criteria.where("tenantId").is(eventRead.getTenantId()),Criteria.where("userId").is(eventRead.getUserId()));
		Query query3 = new Query().addCriteria(c3);
		Update update3 = new Update().addToSet("eventReadTimeList", eventRead.getEventReadTime());
		mongoTemplate.upsert(query3, update3, EventRead.class, collectionName);
	}
}

解释:这段代码是保证每次调用的时候更新最近一次时间使用。因为里面有内置数组对象,笔者想要一次就能实现新增、修改操作,but 能力有限,翻阅大量资料没有借鉴到。所以自己搞了一个逻辑吧。

注意:第一次添加要使用list<EventReadTim>,因为他会生成一个数组,第二次更新的时候使用EventReadTim对象,不然会在相应字段在追加成一个二级数组,不是笔者期望的。

3、mongodb库里的数据结构

/* 1 createdAt:2018/12/3 下午2:34:44*/
{
	"_id" : ObjectId("5c04ce842cc4f25d86d63c22"),
	"tenantId" : "0001",
	"userId" : 264,
	"eventReadTimeList" : [
		{
			"type" : 6,
			"date" : ISODate("2018-12-03T14:35:15.029+08:00")
		},
		{
			"type" : 4,
			"date" : ISODate("2018-12-03T14:35:41.503+08:00")
		}
	]
},

/* 2 createdAt:2018/12/3 上午11:26:29*/
{
	"_id" : ObjectId("5c04a2652cc4f25d86d5fb99"),
	"tenantId" : "0001",
	"userId" : 230,
	"eventReadTimeList" : [
		{
			"type" : 4,
			"date" : ISODate("2018-12-03T13:56:54.552+08:00")
		},
		{
			"type" : 8,
			"date" : ISODate("2018-12-03T14:31:51.318+08:00")
		},
		{
			"type" : 6,
			"date" : ISODate("2018-12-03T14:32:48.782+08:00")
		}
	]
}

 两条记录。

4、查询mongodb的代码

public ResultViewModel<EventRead> findOne(String tenantId,Integer userId,Integer types) {
	//mongodb 语句
	//db.event_Read.aggregate({$project: {tenantId: "$tenantId",userId: "$userId",eventReadTime: {$filter: {input: "$eventReadTime",as: "eventReadTime", cond: {$eq: ["$$eventReadTime.type", 4,]}}}}})
	EventRead eventReadOne=  getEventReadOne(tenantId,userId,types);
	return new ResultViewModel<>(eventReadOne);
}

//抽取公共代码
public EventRead getEventReadOne(String tenantId,Integer userId,Integer types){
	Criteria c = new Criteria().andOperator(Criteria.where("tenantId").is(tenantId),
			Criteria.where("userId").is(userId),
			Criteria.where("eventReadTimeList.type").is(types));
	Query query = new Query();
	query.addCriteria(c);
	EventRead eventReadOne = this.mongoTemplate.findOne(query, EventRead.class, collectionName);
	if (eventReadOne!=null && eventReadOne.getEventReadTimeList()!=null){
		Iterator<EventReadTim> eventReadTimIterator = eventReadOne.getEventReadTimeList().listIterator();
		while (eventReadTimIterator.hasNext()){
			EventReadTim eventReadTim = eventReadTimIterator.next();
			if (eventReadTim.getType().equals(types)){
				eventReadOne.setLastDate(eventReadTim.getDate());
			}
		}
	}
	return eventReadOne;
}

解释:查询的时候,本来可以返回一个对象的,但是spring data mongodb的操作笔者不熟,但是mongodb的过滤我在客户端已经使用了,万全没有问题,所以做个注释,万一以后玩的溜了,在优化。

注意:if下面的代码就是笔者的逻辑处理,就是为啥子我要在Javabean对象单独弄出来一个date类型了。

4、调用查询

ResultViewModel<EventRead> resultViewModel1 = messageSetEventRepository.findOne(usersView.getCompanyPrefix(),usersView.getId(),type);

后期玩熟练了在做一个大总结

偶对了,修改操作还没有

5、修改mongodb

public void upsetEventReads(String tenantId,Integer userId,Integer types) {
	Update update = new Update();
	update.set("eventReadTimeList.$.type", types);
	update.set("eventReadTimeList.$.date", new Date());
	Query query = Query.query(new Criteria().andOperator(Criteria.where("tenantId").is(tenantId),
			Criteria.where("userId").is(userId),
			Criteria.where("eventReadTimeList.type").is(types)));
	mongoTemplate.updateFirst(query, update, EventRead.class,collectionName);
}

6、最后贴上全部的代码

package com.huayi.dayan.mongo;

import com.huayi.dayan.domain.ResultViewModel;
import com.huayi.dayan.domain.mongo.event.EventRead;
import com.huayi.dayan.domain.mongo.event.EventReadTim;
import com.mongodb.BasicDBObject;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;


public class MessageSetEventRepository extends BaseRepository<EventRead>  {

	public MessageSetEventRepository(MongoTemplate mongoTemplate) {
		super(EventRead.class, "event_Read", mongoTemplate);
	}

	/**
	 * 保存消息设置
	 * @param
	 */
	public void upsetEventRead(EventRead eventRead,Integer type) {
		Criteria c = new Criteria().andOperator(Criteria.where("tenantId").is(eventRead.getTenantId()),Criteria.where("userId").is(eventRead.getUserId()));
		Query query = new Query().addCriteria(c);
		EventRead eventReadTem = this.mongoTemplate.findOne(query, EventRead.class, collectionName);
		if (eventReadTem==null){//没有相关记录,第一次添加
			List<EventReadTim> eventReadTimeList = new ArrayList();
			eventReadTimeList.add(eventRead.getEventReadTime());
			Update update = new Update().set("tenantId",eventRead.getTenantId()).set("userId",eventRead.getUserId()).set("eventReadTimeList",eventReadTimeList);
			Query query1 = new Query().addCriteria(c);
			mongoTemplate.upsert(query1, update, EventRead.class, collectionName);
		}else {
			//删除某一个元素
			Criteria c2 = new Criteria().andOperator(Criteria.where("tenantId").is(eventRead.getTenantId()),Criteria.where("userId").is(eventRead.getUserId()),Criteria.where("eventReadTimeList.type").is(type));
			Query query2 = new Query().addCriteria(c2);
			Update update = new Update().pull("eventReadTimeList",new BasicDBObject("type",type));
			mongoTemplate.updateFirst(query2, update, EventRead.class, collectionName);
			//重新追加元素
			Criteria c3 = new Criteria().andOperator(Criteria.where("tenantId").is(eventRead.getTenantId()),Criteria.where("userId").is(eventRead.getUserId()));
			Query query3 = new Query().addCriteria(c3);
			Update update3 = new Update().addToSet("eventReadTimeList", eventRead.getEventReadTime());
			mongoTemplate.upsert(query3, update3, EventRead.class, collectionName);
		}
	}


	public ResultViewModel<EventRead> findOne(String tenantId,Integer userId,Integer types) {
		//mongodb 语句
		//db.event_Read.aggregate({$project: {tenantId: "$tenantId",userId: "$userId",eventReadTime: {$filter: {input: "$eventReadTime",as: "eventReadTime", cond: {$eq: ["$$eventReadTime.type", 4,]}}}}})
		EventRead eventReadOne=  getEventReadOne(tenantId,userId,types);
		return new ResultViewModel<>(eventReadOne);
	}

	//抽取公共代码
	public EventRead getEventReadOne(String tenantId,Integer userId,Integer types){
		Criteria c = new Criteria().andOperator(Criteria.where("tenantId").is(tenantId),
				Criteria.where("userId").is(userId),
				Criteria.where("eventReadTimeList.type").is(types));
		Query query = new Query();
		query.addCriteria(c);
		EventRead eventReadOne = this.mongoTemplate.findOne(query, EventRead.class, collectionName);
		if (eventReadOne!=null && eventReadOne.getEventReadTimeList()!=null){
			Iterator<EventReadTim> eventReadTimIterator = eventReadOne.getEventReadTimeList().listIterator();
			while (eventReadTimIterator.hasNext()){
				EventReadTim eventReadTim = eventReadTimIterator.next();
				if (eventReadTim.getType().equals(types)){
					eventReadOne.setLastDate(eventReadTim.getDate());
				}
			}
		}
		return eventReadOne;
	}

	public void upsetEventReads(String tenantId,Integer userId,Integer types) {
		Update update = new Update();
		update.set("eventReadTimeList.$.type", types);
		update.set("eventReadTimeList.$.date", new Date());
		Query query = Query.query(new Criteria().andOperator(Criteria.where("tenantId").is(tenantId),
				Criteria.where("userId").is(userId),
				Criteria.where("eventReadTimeList.type").is(types)));
		mongoTemplate.updateFirst(query, update, EventRead.class,collectionName);
	}

}

============结束==========

猜你喜欢

转载自blog.csdn.net/sinat_38259539/article/details/84765843