Spring Data with MongoDB (四)
Spring Data with MongoDB
节选自 《Netkiller Spring Cloud 手札》
mongoTemplate
导入与模板相关的包
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;
注入 MongoTemplate 对象
@Autowired
private MongoTemplate mongoTemplate;
Save 保存
User user = new User();
user.setName("Netkiller");
mongoTemplate.save(user, "user");
更新数据
user = mongoTemplate.findOne(Query.query(Criteria.where("name").is("Jam")), User.class);
user.setName("Neo");
mongoTemplate.save(user, "user");
Insert
User user = new User();
user.setName("Neo");
mongoTemplate.insert(user, "user");
BSONObject personBsonObj = BasicDBObjectBuilder.start()
.add("name","Neo Chen")
.add("age",27)
.add("address",null).get();
mongoTemplate.insert(personBsonObj,"personCollection");
document in the db:
db.personCollection.findOne().pretty();
{"age":21,"name":"John Doe";"address":null}*
updateFirst 修改符合条件第一条记录
updateFirst 修改符合条件第一条记录
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Neo"));
Update update = new Update();
update.set("name", "Netkiller");
mongoTemplate.updateFirst(query, update, User.class);
updateMulti 修改符合条件的所有
更新所有数据
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Neo"));
Update update = new Update();
update.set("name", "Jerry");
mongoTemplate.updateMulti(query, update, User.class);
查找并保存
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Luck"));
Update update = new Update();
update.set("name", "Lisa");
User user = mongoTemplate.findAndModify(query, update, User.class);
upsert - 修改符合条件时如果不存在则添加
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Green"));
Update update = new Update();
update.set("name", "Tom");
mongoTemplate.upsert(query, update, User.class);
mongoTemplate.upsert(new Query(Criteria.where("age").is("18")), new Update().set("name", "neo"), collectionName);
删除
User user = new User();
user.setId("5bbf091efd9557069c4a25c5")
mongoTemplate.remove(user, "user");
查找一条数据
public Person findOneByName(String name) {
Query query = new Query();
query.addCriteria(Criteria.where("name").is(name));
return mongoTemplate.findOne(query, Person.class);
}
查找所有数据
public List<Person> findByName(String name) {
Query query = new Query();
query.addCriteria(Criteria.where("name").is(name));
return mongoTemplate.find(query, Person.class);
}
Query
翻页
public List<Person> getAllPersonPaginated(int pageNumber, int pageSize) {
Query query = new Query();
query.skip(pageNumber * pageSize);
query.limit(pageSize);
return mongoTemplate.find(query, Person.class);
}
between
实现一个区间条件 new Criteria("createdDate").gte(beginDate).lte(endDate)
public boolean AccountDeposit(Date beginDate, Date endDate) {
MatchOperation matchOperation = match(new Criteria("createdDate").gte(beginDate).lte(endDate));
GroupOperation groupOperation = group("loginname").sum("amount").as("amount");
SortOperation sortOperation = sort(new Sort(Direction.ASC, "loginname"));
Aggregation aggregation = newAggregation(matchOperation, groupOperation, sortOperation);
AggregationResults<AccountSettlementDetails> results = mongoTemplate.aggregate(aggregation, AccountSettlementDetails.class, AccountSettlementDetails.class);
if (results.getMappedResults() != null) {
log.info(results.getRawResults().get("result").toString());
for (AccountSettlementDetails settlementDetails : results.getMappedResults()) {
log.info("{}", settlementDetails.toString());
return true;
}
Criteria
is
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Neo"));
List<User> users = mongoTemplate.find(query, User.class);
Regex 正则表达式搜索
查询以N开头的名字
Query query = new Query();
query.addCriteria(Criteria.where("name").regex("^N"));
List<User> users = mongoTemplate.find(query,User.class);
查询以o结尾的名字
Query query = new Query();
query.addCriteria(Criteria.where("name").regex("o$"));
List<User> users = mongoTemplate.find(query, User.class);
lt 和 gt
查询年龄小于 < 30 并 > 20 的用户
Query query = new Query();
query.addCriteria(Criteria.where("age").lt(30).gt(20));
List<User> users = mongoTemplate.find(query,User.class);
查找日期范围
Date start = DateUtil.convertStringToDateTime("2014-02-10 20:38:44");
Date end = DateUtil.convertStringToDateTime("2014-02-10 20:38:50");
Query query = new Query();
Criteria criteria = Criteria.where("delflag").is(false);
criteria.and("modifyDate").gte(start).lte(end);
query.addCriteria(criteria);
query.limit(10);
exists()
Query query = new Query();
query.addCriteria(
new Criteria().andOperator(
Criteria.where("field1").exists(true),
Criteria.where("field1").ne(false)
List<Foo> result = mongoTemplate.find(query, Foo.class);
System.out.println("query - " + query.toString());
for (Foo foo : result) {
System.out.println("result - " + foo);
}
包含
public List<Person> findByFavoriteBooks(String favoriteBook) {
Query query = new Query();
query.addCriteria(Criteria.where("favoriteBooks").in(favoriteBook));
return mongoTemplate.find(query, Person.class);
}
Update
set
Update update = new Update();
update.set("name", "Netkiller");
追加数据
Query query = Query.query(Criteria.where("id").is("5bbf091efd9557069c4a25c5"));
Update update = new Update().push("author", new Author("neo", "chen"));
mongoTemplate.updateFirst(query, update, Article.class);
更新数据
Query query = Query.query(Criteria.where("classId").is("1").and("Students.studentId").is("1"));
Update update = Update.update("Students.$.name", "lisa");
mongoTemplate.upsert(query, update, "class");
删除数据
Query query = Query.query(Criteria.where("classId").is("1").and("Students.studentId").is("3"));
Update update = new Update();
update.unset("Students.$");
mongoTemplate.updateFirst(query, update, "class");
inc
public void updateMultiplePersonAge() {
Query query = new Query();
Update update = new Update().inc("age", 1);
mongoTemplate.findAndModify(query, update, Person.class);;
}
update.addToSet
Query query = Query.query(Criteria.where("classId").is("1"));
Student student = new Student("1", "lisa", 3, "girl");
Update update = new Update();
update.addToSet("Students", student);
mongoTemplate.upsert(query, update, "class");
BasicUpdate
BasicUpdate 是底层更新可操作,需要手动实现$set等语句
BasicDBObject basicDBObject = new BasicDBObject();
basicDBObject.put("$set", new BasicDBObject("date","2018-09-09"));
Update update = new BasicUpdate(basicDBObject);
mongoTemplate.updateFirst(new Query(Criteria.where("nickname").is("netkiller")), update,collectionName);
Sort
按照年龄排序
Query query = new Query();
query.with(new Sort(Sort.Direction.ASC, "age"));
List<User> users = mongoTemplate.find(query,User.class);
Query + PageRequest
final Pageable pageableRequest = new PageRequest(0, 2);
Query query = new Query();
query.with(pageableRequest);
newAggregation
MultilevelDirectSellingAccountRewardsSettlementDetails multilevelDirectSellingAccountRewardsSettlementDetails = new MultilevelDirectSellingAccountRewardsSettlementDetails();
multilevelDirectSellingAccountRewardsSettlementDetails.setLoginname("111");
multilevelDirectSellingAccountRewardsSettlementDetails.setPhone("111");
multilevelDirectSellingAccountRewardsSettlementDetails.setRecommenderLoginname("111");
multilevelDirectSellingAccountRewardsSettlementDetails.setRecommenderPhone("111");
multilevelDirectSellingAccountRewardsSettlementDetails.setRecommenderName("Neo");
multilevelDirectSellingAccountRewardsSettlementDetails.setRecommenderType("客户");
multilevelDirectSellingAccountRewardsSettlementDetails.setAmount(5.02);
multilevelDirectSellingAccountRewardsSettlementDetails.setCreatedDate(new Date());
multilevelDirectSellingAccountRewardsSettlementDetailsRepository.save(multilevelDirectSellingAccountRewardsSettlementDetails);
Date beginDate = this.getToday("00:00:00");
Date endDate = this.getToday("23:59:59");
log.info(beginDate.toString() + " ~ " + endDate.toString());
GroupOperation groupOperation = group("loginname").sum("amount").as("amount");
MatchOperation matchOperation = match(new Criteria("createdDate").gte(beginDate).lte(endDate));
SortOperation sortOperation = sort(new Sort(Direction.ASC, "loginname"));
Aggregation aggregation = newAggregation(matchOperation, groupOperation, sortOperation);
AggregationResults<MultilevelDirectSellingAccountRewardsSettlementDetails> results = mongoTemplate.aggregate(aggregation, MultilevelDirectSellingAccountRewardsSettlementDetails.class, MultilevelDirectSellingAccountRewardsSettlementDetails.class);
System.out.println(results.getRawResults().get("result").toString());
创建索引
mongoOps.indexOps(User.class).ensureIndex(new Index().on("name", Direction.ASC));
子对象操作
List 类型
package cn.netkiller.api.domain;
import java.util.List;
import javax.persistence.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class Article {
private String id;
private String title;
private String description;
List<Author> author;
public static class Author {
private String id;
private String firstname;
private String lastname;
public Author(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
更新
db.getCollection('foo').update({"author.firstname":"neo"},{"$set":{"author.$.firstname":"netkiller"}})
更新数据
Query query = Query.query(Criteria.where("author.firstname").is("neo"));
Update update = new Update().set("author.$.firstname", "netkiller");
mongoTemplate.updateFirst(query, update, Article.class);
追加数据
Query query = Query.query(Criteria.where("id").is("5bbf091efd9557069c4a25c5"));
Update update = new Update().push("author", new Author("neo", "chen"));
mongoTemplate.updateFirst(query, update, Article.class);
删除数据
Query query = Query.query(Criteria.where("id").is("5bbf091efd9557069c4a25c5"));
Update update = new Update().pull("author", new Author("jerry", "lee"));
mongoTemplate.updateFirst(query, update, Article.class);
GeoJson 反序列化
正常情况下是不需要做反序列化操作的。如花你想测试,打印一些信息可以这样做。
package cn.netkiller.api.config;
import java.io.IOException;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
public class GeoJsonDeserializer extends JsonDeserializer<GeoJsonPoint> {
@Override
public GeoJsonPoint deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
final JsonNode tree = jsonParser.getCodec().readTree(jsonParser);
final String type = tree.get("type").asText();
final JsonNode coordsNode = tree.get("coordinates");
System.out.println(tree.toString());
System.out.println(type);
System.out.println(coordsNode.toString());
double x = 0;
double y = 0;
if ("Point".equalsIgnoreCase(type)) {
x = coordsNode.get(0).asDouble();
y = coordsNode.get(1).asDouble();
} else {
System.out.println(String.format("No logic present to deserialize %s ", tree.asText()));
final GeoJsonPoint point = new GeoJsonPoint(x, y);
return point;
}
使用 @JsonDeserialize 指定反序列化 Class
@Document
public class Address {