Slide 1

Slide 1 text

Spring Data MongoDB Maciej Walkowiak

Slide 2

Slide 2 text

Agenda NoSQL MongoDB Spring Data Spring Data MongoDB

Slide 3

Slide 3 text

NoSQL

Slide 4

Slide 4 text

NoSQL

Slide 5

Slide 5 text

key-value store document oriented column family based graph NoSQL

Slide 6

Slide 6 text

NoSQL schemaless non-relational cluster friendly Common characteristics

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

document oriented full index support auto-sharding BSON map reduce non-transactional document linking geospatial indexes

Slide 9

Slide 9 text

post collection entry author collection entry { "_id" : ObjectId("5146227a0364038863be7514"), "title" : "post title", "content" : "hello jug", "createdAt" : ISODate("2013-03-17T20:07:22.455Z"), "tags" : [ "mongodb", "jug", "szczecin" ], } { "_id" : ObjectId("514622790364038863be7513"), "name" : "maciej walkowiak", }

Slide 10

Slide 10 text

post collection entry linked with author { "_id" : ObjectId("5146227a0364038863be7514"), "title" : "post title", "content" : "hello world coders", "createdAt" : ISODate("2013-03-17T20:07:22.455Z"), "tags" : [ "mongodb", "jug", "szczecin" ], "author" : DBRef("author", ObjectId("514622790364038863be7513")) }

Slide 11

Slide 11 text

post collection entry with embedded author { "_id" : ObjectId("51476f8d03646a6b3186f081"), "title" : "post title", "content" : "hello world coders", "createdAt" : ISODate("2013-03-18T19:48:29.667Z"), "tags" : [ "mongodb", "jug", "szczecin" ], "author" : { "name" : "maciej walkowiak", "email" : "walkowiak.maciej@yahoo.com" } }

Slide 12

Slide 12 text

db.post.find(); db.post.findOne({ _id: ObjectId("5146227a0364038863be7514") }); db.place.find({ coords : { $near: [-110,32], $maxDistance : 10/111.12 } }) db.post.find({ tags: "szczecin", createdAt: { $gt : ISODate("2013-03-01") } })

Slide 13

Slide 13 text

MongoDB + Java

Slide 14

Slide 14 text

MongoDB + Java

Slide 15

Slide 15 text

MongoDB + Java Morphia Spring Data MongoDB

Slide 16

Slide 16 text

Spring Data

Slide 17

Slide 17 text

Spring Data Same programming model for many databases simple things simple, complex things possible One API to rule them all - nope reduce amount boilerplate code

Slide 18

Slide 18 text

Spring Data Same programming model for many databases simple things simple, complex things possible One API to rule them all - nope reduce amount boilerplate code

Slide 19

Slide 19 text

JPA MongoDB Redis Hadoop Neo4j HBase Spring Data Supported databases

Slide 20

Slide 20 text

mapping template repositories Map Reduce QueryDSL Cross-Store Spring Data

Slide 21

Slide 21 text

Mapping { "_id" : ObjectId("5149471a0364c59b4e743584"), "_class" : "pl.maciejwalkowiak.jug.mongo.Post", "post_title" : "post title", "content" : "hello world coders", "createdAt" : ISODate("2013-03-20T05:20:26.985Z"), "comments" : [ ], "tags" : [ "mongodb", "jug", "szczecin" ], "version" : 0, "author" : DBRef("user", ObjectId("5149471a0364c59b4e743583")) }

Slide 22

Slide 22 text

Mapping @Document public class Post { @Id private ObjectId id; @DBRef private User author; @Field("post_title") private String title; private String content; @CreatedDate private DateTime createdAt; private List comments = new ArrayList(); private Set tags = new HashSet(); @Version private Integer version; ... } { "_id" : ObjectId("5149471a0364c59b4e743584"), "_class" : "pl.maciejwalkowiak.jug.mongo.Post", "post_title" : "post title", "content" : "hello world coders", "createdAt" : ISODate("2013-03-20T05:20:26.985Z"), "comments" : [ ], "tags" : [ "mongodb", "jug", "szczecin" ], "version" : 0, "author" : DBRef("user", ObjectId("5149471a0364c59b4e743583")) }

Slide 23

Slide 23 text

Template interface MongoOperations { T findOne(Query query, Class entityClass); T findAndModify(Query query, Update update, Class entityClass); long count(Query query, String collectionName); void save(Object objectToSave); WriteResult updateMulti(Query query, Update update, Class> entityClass); void remove(Query query, Class entityClass); GroupByResults group(String inputCollectionName, GroupBy groupBy, Class entityClass); MapReduceResults mapReduce(Query query, String inputCollectionName, String mapFunction, String reduceFunction, Class entityClass); CommandResult executeCommand(DBObject command); ... }

Slide 24

Slide 24 text

Repositories DAO in DDD CrudRepository PagingAndSortingRepository declarative find methods

Slide 25

Slide 25 text

Repositories public interface UserRepository extends PagingAndSortingRepository{ User findByName(String name); List findByNameLike(String name, Pageable pageable); }

Slide 26

Slide 26 text

Repositories public interface UserRepository extends PagingAndSortingRepository{ User findByName(String name); List findByNameLike(String name, Pageable pageable); } public interface PostRepository extends CrudRepository, PostRepositoryCustom { @Query("{$where : 'this.content.length > 20'}") List findLongPosts(); @Query("{$where : 'this.content.length > ?0'}") List findPostsLongerThan(int length); }

Slide 27

Slide 27 text

Repositories public interface UserRepository extends PagingAndSortingRepository{ User findByName(String name); List findByNameLike(String name, Pageable pageable); } @Repository public class PostRepositoryImpl implements PostRepositoryCustom { @Autowired private MongoOperations mongoOperations; public Post foo() { return mongoOperations.findOne(Query.query(Criteria.where("title").exists(true)), Post.class); public interface PostRepository extends CrudRepository, PostRepositoryCustom { @Query("{$where : 'this.content.length > 20'}") List findLongPosts(); @Query("{$where : 'this.content.length > ?0'}") List findPostsLongerThan(int length); }

Slide 28

Slide 28 text

Map Reduce // map function () { emit(this.description, 1); }

Slide 29

Slide 29 text

Map Reduce // reduce function (key, values) { var sum = 0; for (var i = 0; i < values.length; i++) sum += values[i]; return sum; } // map function () { emit(this.description, 1); }

Slide 30

Slide 30 text

Map Reduce MapReduceResults results = mongoOperations.mapReduce("collectionName", "classpath:map.js", "classpath:reduce.js", ValueObject.class); // reduce function (key, values) { var sum = 0; for (var i = 0; i < values.length; i++) sum += values[i]; return sum; } // map function () { emit(this.description, 1); }

Slide 31

Slide 31 text

QueryDSL Type-Safe criteria API

Slide 32

Slide 32 text

QueryDSL @Generated("com.mysema.query.codegen.EntitySerializer") public class QPost extends EntityPathBase { private static final long serialVersionUID = -1782980951; private static final PathInits INITS = PathInits.DIRECT; public static final QPost post = new QPost("post"); public final QUser author; public final ListPath comments = this.createList("comments", Comment.class, QComment.class, PathInits.DIRECT); public final StringPath content = createString("content"); public final org.joda.time.QDateTime createdAt; public final org.bson.types.QObjectId id; Type-Safe criteria API

Slide 33

Slide 33 text

QueryDSL postRepository.findAll(QPost.post.content.contains("hello"))); @Generated("com.mysema.query.codegen.EntitySerializer") public class QPost extends EntityPathBase { private static final long serialVersionUID = -1782980951; private static final PathInits INITS = PathInits.DIRECT; public static final QPost post = new QPost("post"); public final QUser author; public final ListPath comments = this.createList("comments", Comment.class, QComment.class, PathInits.DIRECT); public final StringPath content = createString("content"); public final org.joda.time.QDateTime createdAt; public final org.bson.types.QObjectId id; Type-Safe criteria API

Slide 34

Slide 34 text

Demo

Slide 35

Slide 35 text

MongoDB as a Service 0.5GB for free

Slide 36

Slide 36 text

Q&A

Slide 37

Slide 37 text

Contact walkowiak.maciej@yahoo.com @MaciejWalkowiak http://maciejwalkowiak.pl/