知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/
注意Spring4 與 1.9.1.RELEASE有兼容性問題,日誌提示 Error creating bean with name 'mongoTemplate' defined in ServletContext resource
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>1.8.1.RELEASE</version> </dependency>
<mongo:db-factory id="mongoDbFactory" host="${mongo.host}" port="${mongo.port}" dbname="${mongo.database}" /> <!-- username="${mongo.username}" password="${mongo.password}" --> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/> </bean> <mongo:mapping-converter id="converter" db-factory-ref="mongoDbFactory"/> <bean id="gridFsTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate"> <constructor-arg ref="mongoDbFactory"/> <constructor-arg ref="converter"/> </bean>
例 8.2. Spring Data MongoDB - springframework-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd "> <mvc:resources location="/images/" mapping="/images/**" /> <mvc:resources location="/css/" mapping="/css/**" /> <mvc:resources location="/js/" mapping="/js/**" /> <mvc:resources location="/zt/" mapping="/zt/**" /> <mvc:resources location="/sm/" mapping="/sm/**" /> <mvc:resources location="/module/" mapping="/module/**" /> <context:component-scan base-package="cn.netkiller.controller" /> <!-- <context:property-placeholder location="classpath:resources/development.properties" /> --> <mvc:annotation-driven /> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <bean id="configuracion" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:resources/development.properties" /> </bean> <!-- MongoDB Connection Factory --> <mongo:db-factory id="mongoDbFactory" host="${mongo.host}" port="${mongo.port}" dbname="${mongo.database}" /> <!-- username="${mongo.username}" password="${mongo.password}" --> <!-- MongoDB template definition --> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/> </bean> <!-- MongoDB GridFS template definition --> <mongo:mapping-converter id="converter" db-factory-ref="mongoDbFactory"/> <bean id="gridFsTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate"> <constructor-arg ref="mongoDbFactory"/> <constructor-arg ref="converter"/> </bean> <!-- Redis Connection Factory --> <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="192.168.2.1" p:port="6379" p:use-pool="true" /> <!-- redis template definition --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnFactory" /> </beans>
development.properties 配置內容
mongo.host=192.168.4.1 mongo.port=27017 mongo.username=test mongo.password=passw0rd mongo.database=website
package cn.netkiller.pojo; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document(collection = "tracker") public class Tracker { @Id private String id; private String name; private String unique; private String hostname; private String referrer; private String href; public Tracker() { // TODO Auto-generated constructor stub } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUnique() { return unique; } public void setUnique(String unique) { this.unique = unique; } public String getHostname() { return hostname; } public void setHostname(String hostname) { this.hostname = hostname; } public String getReferrer() { return referrer; } public void setReferrer(String referrer) { this.referrer = referrer; } public String getHref() { return href; } public void setHref(String href) { this.href = href; } @Override public String toString() { return "Tracker [id=" + id + ", name=" + name + ", unique=" + unique + ", hostname=" + hostname + ", referrer=" + referrer + ", href=" + href + "]"; } }
package cn.netkiller.controller; import cn.netkiller.pojo.Tracker; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; @Controller public class TrackerController { @Autowired private MongoTemplate mongoTemplate; public TrackerController() { } @RequestMapping("/tracker/test") @ResponseBody String hello() { return "Hello World!"; } @RequestMapping("/tracker") @ResponseBody String execute() { Tracker tracker = new Tracker(); tracker.setName("test"); tracker.setUnique("111223456"); tracker.setHostname("www.example.com"); tracker.setHref("http://example.com/test.html"); tracker.setReferrer("http://example.com/"); this.mongoTemplate.insert(tracker); return tracker.toString(); } }
> db.tracker.find(); { "_id" : ObjectId("5757c0b92c526a6bda5eea3a"), "_class" : "cn.netkiller.repositories.Tracker", "name" : "test", "unique" : "111223456", "hostname" : "www.example.com", "referrer" : "http://example.com/", "href" : "http://example.com/test.html" }
複雜的 @Document 數據類型定義
package cn.netkiller.domain; import java.util.Date; import java.util.List; import java.util.Map; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document public class MultilevelDirectSellingTradingRebate { public enum Type { POINT, CASH, GIFT } public enum Rebate { DIRECT, INDIRECT } public enum Status { New, Rejected, Approved } @Id private String id; public String name; public Date beginDate; public Date endDate; public double lowAmount; public double highAmount; public Type type; public Status status = Status.New; public List<Map<String, Map<?, ?>>> product; @Override public String toString() { return "MultilevelDirectSellingTradingRebate [id=" + id + ", name=" + name + ", beginDate=" + beginDate + ", endDate=" + endDate + ", lowAmount=" + lowAmount + ", highAmount=" + highAmount + ", type=" + type + ", status=" + status + ", product=" + product + "]"; } }
預設使用 class 作為表名
@Document public class Multilevel { ... ... }
指定特別表名
@Document(collection = "author")
索引
稀疏索引允許唯一索引存在多個 null 值
@Indexed(unique = true, sparse = true) private String uuid; @Indexed(unique = true, sparse = true) private String transactionId = null;
@Document @CompoundIndexes({ @CompoundIndex(name = "email_age", def = "{'email.id' : 1, 'age': 1}") }) public class User { // }
@Document @CompoundIndexes({ @CompoundIndex(def = "{'firstName':1, 'salary':-1}", name = "compound_index_1"), @CompoundIndex(def = "{'secondName':1, 'profession':1}", name = "compound_index_2") }) public class Person { @Id private String id; private String firstName; private String secondName; private LocalDateTime dateOfBirth; private Address address; private String profession; private int salary; // constructor // getters and setters }
@Document(language = "spanish") class SomeEntity { @TextIndexed String foo; @Language String lang; Nested nested; } class Nested { @TextIndexed(weight=5) String bar; String roo; }
點數據索引
@GeoSpatialIndexed private GeoJsonPoint location; // GPS 定位信息
2D 數據索引
@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
public class User { @Transient private Integer age; // standard getter and setter }
package cn.netkiller.api.domain; import java.util.List; import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Document; @Document public class Article { private String title; // 名稱 private String description; // 描述 private String tag; // 類型 @DBRef private List<Hypermedia> hypermedia; // 圖片,視頻 public Article() { // TODO Auto-generated constructor stub } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getTag() { return tag; } public void setTag(String tag) { this.tag = tag; } public List<Hypermedia> getHypermedia() { return hypermedia; } public void setHypermedia(List<Hypermedia> hypermedia) { this.hypermedia = hypermedia; } @Override public String toString() { return "Article [title=" + title + ", description=" + description + ", tag=" + tag + ", hypermedia=" + hypermedia + "]"; } }
package api.domain; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document public class Hypermedia { @Id private String id; private String hash; private String name; private String size; public Hypermedia() { // TODO Auto-generated constructor stub } public Hypermedia(String hash, String name, String size) { this.hash = hash; this.name = name; this.size = size; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getHash() { return hash; } public void setHash(String hash) { this.hash = hash; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSize() { return size; } public void setSize(String size) { this.size = size; } @Override public String toString() { return "Hypermedia [id=" + id + ", hash=" + hash + ", name=" + name + ", size=" + size + "]"; } }
如果你只查詢 Article 表,不會單獨查詢 Hypermedia,返回結果可以掩藏 Id ,不寫 get/set 方法即可。
package cn.netkiller.api.domain; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document public class Hypermedia { @Id private String id; private String hash; private String name; private String size; public Hypermedia() { // TODO Auto-generated constructor stub } public Hypermedia(String hash, String name, String size) { this.hash = hash; this.name = name; this.size = size; } public String getHash() { return hash; } public void setHash(String hash) { this.hash = hash; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSize() { return size; } public void setSize(String size) { this.size = size; } @Override public String toString() { return "Hypermedia [hash=" + hash + ", name=" + name + ", size=" + size + "]"; } }
package cn.netkiller.api.repository; import org.springframework.data.mongodb.repository.MongoRepository; import api.domain.Article; public interface ArticleRepository extends MongoRepository<Article, String> { }
package cn.netkiller.api.repository; import org.springframework.data.mongodb.repository.MongoRepository; import api.domain.Hypermedia; public interface HypermediaRepository extends MongoRepository<Hypermedia, String> { }
package cn.netkiller.api.restful; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import api.domain.Article; import api.domain.Hypermedia; import api.repository.ArticleRepository; import api.repository.HypermediaRepository; @RestController @RequestMapping("/article") public class ArticleRestController { @Autowired private ArticleRepository articleRepository; @Autowired private HypermediaRepository hypermediaRepository; public ArticleRestController() { // TODO Auto-generated constructor stub } @GetMapping("/save") public Article save() { Article article = new Article(); article.setTitle("標題"); article.setDescription("摘要"); article.setTag("標籤"); Hypermedia hypermedia = new Hypermedia("AAA", "BBB", "CCC"); hypermediaRepository.save(hypermedia); List<Hypermedia> hypermedias = new ArrayList<Hypermedia>(); hypermedias.add(hypermedia); article.setHypermedia(hypermedias); articleRepository.save(article); System.out.println(article); return article; } }
neo@MacBook-Pro ~ % curl -s -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer ${TOKEN}" -X GET ${URL}/article/save | jq { "title": "標題", "description": "摘要", "tag": "標籤", "hypermedia": [ { "hash": "AAA", "name": "BBB", "size": "CCC" } ] }
MongoDB 結果
db.getCollection('article').find({})
/* 1 */ { "_id" : ObjectId("5bab66f8c92782395817cb05"), "title" : "標題", "description" : "摘要", "tag" : "標籤", "hypermedia" : [ { "$ref" : "hypermedia", "$id" : ObjectId("5bab66f8c92782395817cb04") } ], "_class" : "cn.netkiller.api.domain.Article" }
db.getCollection('hypermedia').find({})
/* 1 */ { "_id" : ObjectId("5bab66b9c927823951f4f5fe"), "hash" : "AAA", "name" : "BBB", "size" : "CCC", "_class" : "api.domain.Hypermedia" }
@DateTimeFormat( pattern = "yyyy-MM-dd" ) private Date birthday @DateTimeFormat(iso = DateTimeFormat.ISO.NONE) private final Calendar datetime; @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date date; @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) private Date createdDate = new Date();
public enum Type { POINT, CASH, GIFT } public enum Rebate { DIRECT, INDIRECT } public enum Status { New, Rejected, Approved }
枚舉類型的賦值方法
MultilevelDirectSellingTradingRebate multilevelDirectSellingTradingRebate = new MultilevelDirectSellingTradingRebate(); multilevelDirectSellingTradingRebate.name = "TEST"; multilevelDirectSellingTradingRebate.beginDate = new Date(); multilevelDirectSellingTradingRebate.endDate = new Date(); multilevelDirectSellingTradingRebate.lowAmount = 1.5d; multilevelDirectSellingTradingRebate.highAmount = 100d; multilevelDirectSellingTradingRebate.type = Type.CASH;
public List<Map<String, Map<?, ?>>> product;
下面是數據集結構的賦值例子
Map<Enum<Rebate>, Double> rebate = new HashMap<Enum<Rebate>, Double>(); rebate.put(Rebate.DIRECT, 10.05d); rebate.put(Rebate.INDIRECT, 6.05d); Map<String, Map<?, ?>> prod1 = new HashMap<String, Map<?, ?>>(); prod1.put("USDRMB", rebate); List<Map<String, Map<?, ?>>> products = new ArrayList<Map<String, Map<?, ?>>>(); products.add(prod1); multilevelDirectSellingTradingRebate.product = products;
預設不需要設置,除非你的包不在當前包下,或者命令不是 repository。
@EnableMongoRepositories(basePackages = "cn.netkiller.repository")
@RequestMapping(value = "read", method = RequestMethod.GET, produces = { "application/xml", "application/json" }) @ResponseStatus(HttpStatus.OK) public List<Withdraw> read() { return repository.findAll(); }
List<User> findByName(String name); List<User> users = userRepository.findByName("Eric");
List<User> users = userRepository.findAll(new Sort(Sort.Direction.ASC, "name"));
Pageable pageable = PageRequest.of(0, 1); Page<User> page = userRepository.findAll(pageable); List<User> users = pages.getContent();
Page<User> findByLastname(String lastname, Pageable pageable);
@RequestMapping(value = "read/{size}/{page}", method = RequestMethod.GET, produces = { "application/xml", "application/json" }) @ResponseStatus(HttpStatus.OK) public List<Withdraw> readPage(@PathVariable int size, @PathVariable int page){ PageRequest pageRequest = new PageRequest(page-1,size); return repository.findAll(pageRequest).getContent(); }
URL翻頁參數,每次返回10條記錄
第一頁 http://localhost:8080/v1/withdraw/read/10/1.json 第二頁 http://localhost:8080/v1/withdraw/read/10/2.json ... 第五頁 http://localhost:8080/v1/withdraw/read/10/5.json
List<User> findByNameStartingWith(String regexp); List<User> findByNameEndingWith(String regexp); List<User> users = userRepository.findByNameStartingWith("N"); List<User> users = userRepository.findByNameEndingWith("o");
數值範圍
List<User> findByAgeBetween(int ageGT, int ageLT); List<User> users = userRepository.findByAgeBetween(20, 50);
日期範圍,取值 e.g. 2018-07-04 00:00:00 and 2018-07-04 23:59:59
List<Member> findByCreatedDateBetween(DateTime start, DateTime end); List<Member> findByCreatedDate(@Temporal(TemporalType.DATE) Date date);
List<Assets> findAllByUpdateDateBefore(Date yesterday); List<Assets> findAllByUpdateDateBeforeAndStatus(Date yesterday, String status); List<Assets> findAllByUpdateDateAfter(Date yesterday);
public interface PersonRepository extends MongoRepository<Person, String> { @Query("{ 'name' : ?0 }") List<Person> findWithQuery(String userId); } @Query(value = "{'statusHistories':{$elemMatch:{'status':{$in:['PROCESSABLE']}}},'created' : { '$gt' : { '$date' : ':?0' } , '$lt' : { '$date' : ':?1'}}}", count = true) Long countMe(@Param("dateFrom") Date datefrom, @Param("dateTo") Date dateTo);
導入與模板相關的包
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;
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");
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 修改符合條件第一條記錄
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);
更新所有數據
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);
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); }
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); }
實現一個區間條件 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; }
Query query = new Query(); query.addCriteria(Criteria.where("name").is("Neo")); List<User> users = mongoTemplate.find(query, User.class);
查詢以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);
查詢年齡小於 < 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);
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); }
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");
public void updateMultiplePersonAge() { Query query = new Query(); Update update = new Update().inc("age", 1); mongoTemplate.findAndModify(query, update, Person.class);; }
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);
按照年齡排序
Query query = new Query(); query.with(new Sort(Sort.Direction.ASC, "age")); List<User> users = mongoTemplate.find(query,User.class);
final Pageable pageableRequest = new PageRequest(0, 2); Query query = new Query(); query.with(pageableRequest);
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());
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 { @Id 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);
正常情況下是不需要做反序列化操作的。如花你想測試,打印一些信息可以這樣做。
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 { @Id private String id; // @GeoSpatialIndexed @JsonDeserialize(using = GeoJsonDeserializer.class) private GeoJsonPoint location; // GPS 定位信息 }