SlideShare a Scribd company logo
1 of 63
Morphia: Simplifying
Persistence for Java and
MongoDB
Jeff Yemin
Java Evangelist, 10gen
MongoDB on the JVM
• MongoDB Java Driver
  – Map-based API

• JVM language integrations
  – Casbah (Scala)
  – Jmongo (Ruby)
  – Monger (Clojure)

• ODM (Object Document Mapper)
  – Morphia
  – Spring Data MongoDB
Morphia
• Object Document Mapper
  – Specified with annotations
  – Implemented with reflection

• Fluent query and update APIs
  – Runtime validation
Morphia by Example
• Model
• Test
• Output
Dependencies
<dependency>
  <groupId>org.mongodb</groupId>
  <artifactId>mongo-java-driver</artifactId>
  <version>2.10.1</version>
</dependency>

<dependency>
  <groupId>com.google.code.morphia</groupId>
  <artifactId>morphia</artifactId>
  <version>0.99</version>
</dependency>
Repository
<repository>
  <id>morphia</id>
  <name>Morphia</name>
  <url>http://morphia.googlecode.com/svn/mavenrepo/</url>
  <layout>default</layout>
</repository>
Create the Datastore
Morphia morphia = new Morphia();
Mongo mongo = new Mongo();
Datastore ds = morphia.createDatastore(mongo, "test");
Entity Modelling
Let's model github
First Entity (model)
class Programmer {
   String name;
}
First Entity (test)
Programmer programmer = new Programmer();
programmer.name= "Scott Hernandez";

ds.save(programmer);
First Entity (shell)
> db.Programmer.findOne()
{
    "_id" : ObjectId("503292d51aa814c051554696"),
    "className" : "demo.Programmer",
    "name" : "Scott Hernandez"
}
@Id (model)
class Programmer {
   @Id ObjectId id;
   String name;
   public void toString() {…}
}
@Id (test)
Programmer programmer = new Programmer();
programmer.name= "Scott Hernandez";

ds.save(programmer);
System.out.println(programmer)
@Id (toString)
Programmer{id=5032935f1aa8a8aa3485b441,
      name='Scott Hernandez'}
String Id (model)
class Programmer {
   @Id String githubUserName;
   String name;
}
String Id (test)
Programmer programmer = new Programmer();
programmer.githubUserName = "scotthernandez";
programmer.name= "Scott Hernandez";

ds.save(programmer);
String Id (shell)
> db.Programmer.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    "name" : "Scott Hernandez"
}
@Entity (model)
@Entity("programmers")
class Programmer {
   @Id String githubUserName;
   String name;
}
@Entity (shell)
> db.programmers.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    "name" : "Scott Hernandez"
}
More primitives (model)
@Entity("programmers")
class Programmer {
   @Id String githubUserName;
   String name;
   Date memberSince;
   boolean active;
   int followers;
}
More primitives (test)
Programmer scott = new Programmer();
scott.userName = "scotthernandez";
scott.name = "Scott Hernandez";
scott.since = dateFmt.parse("Aug 12, 2009");
scott.active = true;
scott.followers = 8;

ds.save(scott);
More primitives (shell)
> db.programmers.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    "name" : "Scott Hernandez",
    "memberSince" : ISODate("2009-08-12T04:00:00Z"),
    "active" : true,
    "followers" : 8
}
Primitive Array (Model)
@Entity("programmers")
class Programmer {
   @Id String githubUserName;
   String name;
   Date memberSince;
   boolean active;
   int followers;
   List<String> following;
}
Primitive Array (test)
Programmer scott = new Programmer();
scott.userName = "scotthernandez";
scott.name = "Scott Hernandez";
scott.since = dateFmt.parse("Aug 12, 2009");
scott.active = true;
scott.followers = 8;
scott.following = Arrays.asList("moraes", "stickfigure");

ds.save(scott);
Primitive Array (shell)
 db.programmers.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    "name" : "Scott Hernandez",
    "memberSince" : ISODate("2009-08-12T04:00:00Z"),
    "active" : true,
    "followers" : 8,
    "following" : [
         "moraes",
         "stickfigure"
    ]
}
@Embedded (model)
@Entity("programmers")
class Programmer {
   @Id String githubUserName;
   Name name;
   Date memberSince;
   boolean active;
   int followers;
   List<String> following;
}

@Embedded
class Name {
   String first, last;
}
@Embedded (test)
Programmer programmer = new Programmer();
programmer.githubUserName = "scotthernandez";
programmer.name = new Name("Scott", "Hernandez");
programmer.memberSince = dateFmt.parse("Aug 12, 2009");
programmer.active = true;
programmer.followers = 8;
programmer.following = Arrays.asList("moraes", "stickfigure");

ds.save(programmer);
@Embedded (shell)
> db.programmers.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    "name" : {
               "first" : "Scott",
               "last" : "Hernandez"
    },
    "memberSince" : ISODate("2009-08-12T04:00:00Z"),
    "active" : true,
    "followers" : 8,
    "following" : [
               "moraes",
               "stickfigure"
    ]
}
@Embedded List (model)
@Entity("programmers")
class Programmer {
   @Id String githubUserName;
   Name name;
   Date memberSince;
   boolean active;
   int followers;
   List<String> following;
   List<Repository> repositories;
}
@Embedded
class Name {
   String first, last;
}
@Embedded
class Repository {
   String name;
   String forkedFrom;
}
@Embedded (test)
Programmer programmer = new Programmer();
programmer.githubUserName = "scotthernandez";
programmer.name = new Name("Scott", "Hernandez");
programmer.memberSince = dateFmt.parse("Aug 12, 2009");
programmer.active = true;
programmer.followers = 8;
programmer.following = Arrays.asList("moraes", "stickfigure");
programmer.repositories = Arrays.asList(
   new Repository("docs", "mongodb/docs"),
   new Repository("mongo-java-driver", "mongodb/mongo-java-driver"));

ds.save(programmer);
@Embedded List (shell)
> db.programmers.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    …
    "repositories" : [
         {
              "name" : "docs",
              "forkedFrom" : "mongodb/docs"
         },
         {
              "name" : "mongo-java-driver",
              "forkedFrom" : "mongodb/mongo-java-driver"
         }
    ]
}
@Reference (model)
@Entity("repos")
class Repository {
   @Id ObjectId id;
   @Reference Programmer owner;
   String name;
   String forkedFrom;
}
@Reference (test)
Programmer programmer = new Programmer();
programmer.githubUserName = "scotthernandez";
programmer.name = new Name("Scott", "Hernandez");
programmer.memberSince = dateFmt.parse("Aug 12, 2009");
programmer.active = true;
programmer.followers = 8;
programmer.following = Arrays.asList("moraes", "stickfigure");

ds.save(programmer);

Repository repo = new Repository(programmer, "docs",
                    "mongodb/docs");

ds.save(repo);
@Reference (shell)
> db.repos.findOne()
{
    "_id" : ObjectId("503297e31aa8255abe542aaa"),
    "className" : "demo.Repository",
    "owner" : DBRef("programmers", "scotthernandez"),
    "name" : "docs",
    "forkedFrom" : "mongodb/docs"
}
Small schema change (model)
abstract class Member {
  @Id String userName;
  @Property("memberSince") Date since;
  boolean active;
  String name;
}
@Entity("programmers")
class Programmer extends Member {
   int followers;
   List<String> following;
}
@Entity("orgs")
class Organization extends Member {
}
@Entity("repos")
class Repository {
   @Id ObjectId id;
   @Reference Member owner;
   String name;
   @Reference(lazy=true) Repository forkedFrom;
}
Small schema change (test)
Programmer scott = new Programmer();
//…
ds.save(scott);

// save mongodb Organization
Organization mongodb = new Organization("mongodb",
       "mongodb", sdf.parse("Jan 8, 2009"));
ds.save(mongodb);

// save mongodb's docs Repository
Repository mongoDocs = new Repository(mongodb, "docs");
ds.save(mongoDocs);

// save Scott's forked docs Repository
Repository scottDocs = new Repository(scott, "docs",
                          mongoDocs);
ds.save(scottDocs);
Small schema change (shell)
> db.orgs.findOne()
{
    "_id" : "mongodb",
    "className" : "demo.Organization",
    "memberSince" : ISODate("2009-01-08T05:00:00Z"),
    "active" : false,
    "name" : "mongodb"
}
> db.programmers.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    "memberSince" : ISODate("2009-08-12T04:00:00Z"),
    "active" : true,
    "name" : "Scott Hernandez"
      …
}
Small schema change (shell, 2)
> db.repos.find().toArray()
[
    {
        "_id" : ObjectId("503298be1aa8b1d255e5d45b"),
        "className" : "demo.Repository",
        "owner" : DBRef("orgs", "mongodb"),
        "name" : "docs"
    },
    {
        "_id" : ObjectId("503298be1aa8b1d255e5d45c"),
        "className" : "demo.Repository",
        "owner" : DBRef("programmers", "scotthernandez"),
        "name" : "docs",
        "forkedFrom" : DBRef("repos",
    ObjectId("503298be1aa8b1d255e5d45b"))
    }
]
Querying
Find by Equality (test)
•   ds.get(Programmer.class, "scotthernandez")

•   ds.find(Programmer.class, "name", "Scott Hernandez")

•   ds.find(Programmer.class).field("name").equal("Scott Hernandez”)
Find by Equality (logs)
•   test.programmers query: { _id: "scotthernandez" }

•   test.programmers query: { name: "Scott Hernandez" }

•   test.programmers query: { name: "Scott Hernandez" }
Find by Range (test)
•   ds.find(Programmer.class).field("followers").greaterThan(0)

•   ds.find(Programmer.class).filter("followers >", 0)

•   ds.find(Programmer.class).field("memberSince").lessThan(sdf.parse("Jan 1, 2010"))
Find by Range (logs)
•   test.programmers query: { followers: { $gt: 0 } }

•   test.programmers query: { followers: { $gt: 0 } }

•   test.programmers query: { memberSince: { $lt: new Date(1262322000000) } }
Combining conditions (test)
ds.find(Programmer.class).
    field("memberSince").lessThan(dateFmt.parse("Jan 1, 2010")).
     field("followers").greaterThan(0)
Combining conditions (logs)
test.programmers query: {
  memberSince: { $lt: new Date(1262322000000) },
  followers: { $gt: 0 }
}
Find by Reference                            (test)

Programmer scott = new Programmer("scotthernandez")
ds.find(Repository.class).field("owner").equal(scott)
Find by Reference (logs)
test.repos query: {
  owner: { $ref: "programmers", $id: "scotthernandez" }
}
Indexing
@Indexed
• Annotation for fields
   –   value (IndexDirection)
   –   name (String)
   –   unique (boolean)
   –   dropDups (boolean)
   –   background (boolean)
   –   sparse (boolean)
• Examples
   – @Indexed(value=IndexDirection.ASC, name="followers") int followers;
   – @Indexed @Reference Repository forkedFrom;
@Indexes and @Index
• @Indexes: Annotation for types
  – value (Index[])

• @Index
  – value (String)
  – Others same as @Indexed

• Examples
  – @Indexes(@Index("since, -followers")) public class
    Programmer {…}
Updating
Updating with save (test)
Programmer jeff = createJeff();
ds.save(jeff);

// jeff is following scott, so increment
// scott's followers and re-save
Programmer scott = ds.get(Programmer.class,
                    "scotthernandez")

scott.followers++;
ds.save(scott);
Updating with save (logs)
update test.programmers

query: {
  _id: "scotthernandez",
}
update: {
  _id: "scotthernandez",
  className: "demo.Programmer",
  followers: 9,
  following: [ "moraes", "stickfigure" ],
  memberSince: new Date(1250049600000),
  active: true,
  name: "Scott Hernandez",
}
Updating with save (shell)
> db.programmers.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    "followers" : 9,
    "following" : [
         "moraes",
         "stickfigure"
    ],
    "memberSince" : ISODate("2009-08-12T04:00:00Z"),
    "active" : true,
    "name" : "Scott Hernandez"
}
Optimistic Concurrency (model)
@Entity
public abstract class Member {
  @Id String userName;
  @Property("memberSince") Date since;
  boolean active;
  String name;
  @Version Long version;
}
Optimistic Concurrency (logs)
update test.programmers

query: {
   _id: "scotthernandez",
   version: 1345497713173
 }
update: {
   _id: "scotthernandez",
   className: "demo.Programmer",
   followers: 9,
   following: [ "moraes", "stickfigure" ],
   memberSince: new Date(1250049600000),
   active: true,
   name: "Scott Hernandez",
   version: 1345497718181
}
Optimistic Concurrency
(shell)
> db.programmers.findOne()
{
    "_id" : "scotthernandez",
    "className" : "demo.Programmer",
    "followers" : 9,
    "following" : [
              "moraes",
              "stickfigure"
    ],
    "memberSince" : ISODate("2009-08-12T04:00:00Z"),
    "active" : true,
    "name" : "Scott Hernandez",
    "version" : NumberLong("1345497718181")
}
UpdateOperations (test)
Programmer jeff = createJeff();
ds.save(jeff);

// increment followers of scott by one
UpdateOperations<Programmer> incrementFollowing =
 ds.createUpdateOperations(Programmer.class).
         inc("followers", 1);


Query<Programmer> queryForScott =
 ds.find(Programmer.class, "_id", "scotthernandez");


ds.update(queryForScott, incrementFollowing);
UpdateOperations (logs)
update test.programmers

query: {
  _id: "scotthernandez"
}

update: {
  $inc: { followers: 1 }
}
Web Resources
• Morphia home: http://code.google.com/p/morphia/
• Morphia user group:
  https://groups.google.com/forum/?fromgroups#!forum/morphia

• Demo code: https://github.com/jyemin/morphia-demo
    – Separate commit and tag for each slide, so you can play
      along
Thanks!
• Jeff Yemin
   – https://twitter.com/@jeffyemin
   – jeff.yemin@10gen.com
   – https://github.com/jyemin/
Thank You
Jeff Yemin
Engineering Manager, 10gen

More Related Content

What's hot

MongoDB + Java + Spring Data
MongoDB + Java + Spring DataMongoDB + Java + Spring Data
MongoDB + Java + Spring Data
Anton Sulzhenko
 
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
Donghyeok Kang
 
MongoDB (Advanced)
MongoDB (Advanced)MongoDB (Advanced)
MongoDB (Advanced)
TO THE NEW | Technology
 
Java Development with MongoDB
Java Development with MongoDBJava Development with MongoDB
Java Development with MongoDB
Scott Hernandez
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
Kiyotaka Oku
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
Jonathan Wage
 

What's hot (20)

Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDB
 
MongoDB + Java + Spring Data
MongoDB + Java + Spring DataMongoDB + Java + Spring Data
MongoDB + Java + Spring Data
 
Morphia, Spring Data & Co.
Morphia, Spring Data & Co.Morphia, Spring Data & Co.
Morphia, Spring Data & Co.
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring Data
 
Search Evolution - Von Lucene zu Solr und ElasticSearch
Search Evolution - Von Lucene zu Solr und ElasticSearchSearch Evolution - Von Lucene zu Solr und ElasticSearch
Search Evolution - Von Lucene zu Solr und ElasticSearch
 
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
[제1회 루씬 한글분석기 기술세미나] solr로 나만의 검색엔진을 만들어보자
 
Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
 
Softshake - Offline applications
Softshake - Offline applicationsSoftshake - Offline applications
Softshake - Offline applications
 
MongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() OutputMongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() Output
 
MongoDB (Advanced)
MongoDB (Advanced)MongoDB (Advanced)
MongoDB (Advanced)
 
Java Development with MongoDB
Java Development with MongoDBJava Development with MongoDB
Java Development with MongoDB
 
Elastic search 검색
Elastic search 검색Elastic search 검색
Elastic search 검색
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
ElasticSearch for .NET Developers
ElasticSearch for .NET DevelopersElasticSearch for .NET Developers
ElasticSearch for .NET Developers
 
A evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no androidA evolução da persistência de dados (com sqlite) no android
A evolução da persistência de dados (com sqlite) no android
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
Fazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearchFazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearch
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
 

Similar to Webinar: Simplifying Persistence for Java and MongoDB

Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDB
MongoDB
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
Sven Haiges
 
Terrastore - A document database for developers
Terrastore - A document database for developersTerrastore - A document database for developers
Terrastore - A document database for developers
Sergio Bossa
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
Mario Fusco
 
Building Your First Application with MongoDB
Building Your First Application with MongoDBBuilding Your First Application with MongoDB
Building Your First Application with MongoDB
MongoDB
 

Similar to Webinar: Simplifying Persistence for Java and MongoDB (20)

Building Your First MongoDB App
Building Your First MongoDB AppBuilding Your First MongoDB App
Building Your First MongoDB App
 
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
Jan Stępień - GraalVM: Fast, Polyglot, Native - Codemotion Berlin 2018
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
Dev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDBDev Jumpstart: Build Your First App with MongoDB
Dev Jumpstart: Build Your First App with MongoDB
 
Green dao
Green daoGreen dao
Green dao
 
Hands On Spring Data
Hands On Spring DataHands On Spring Data
Hands On Spring Data
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Tutorial on developing a Solr search component plugin
Tutorial on developing a Solr search component pluginTutorial on developing a Solr search component plugin
Tutorial on developing a Solr search component plugin
 
Building your first app with mongo db
Building your first app with mongo dbBuilding your first app with mongo db
Building your first app with mongo db
 
Mongo+java (1)
Mongo+java (1)Mongo+java (1)
Mongo+java (1)
 
Terrastore - A document database for developers
Terrastore - A document database for developersTerrastore - A document database for developers
Terrastore - A document database for developers
 
Entity Framework Core & Micro-Orms with Asp.Net Core
Entity Framework Core & Micro-Orms with Asp.Net CoreEntity Framework Core & Micro-Orms with Asp.Net Core
Entity Framework Core & Micro-Orms with Asp.Net Core
 
Gradle
GradleGradle
Gradle
 
CouchDB-Lucene
CouchDB-LuceneCouchDB-Lucene
CouchDB-Lucene
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
Building Your First Application with MongoDB
Building Your First Application with MongoDBBuilding Your First Application with MongoDB
Building Your First Application with MongoDB
 
Schema Design with MongoDB
Schema Design with MongoDBSchema Design with MongoDB
Schema Design with MongoDB
 
Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling
 
Best of build 2021 - C# 10 & .NET 6
Best of build 2021 -  C# 10 & .NET 6Best of build 2021 -  C# 10 & .NET 6
Best of build 2021 - C# 10 & .NET 6
 

More from MongoDB

More from MongoDB (20)

MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
 
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 MongoDB SoCal 2020: MongoDB Atlas Jump Start MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

Webinar: Simplifying Persistence for Java and MongoDB

  • 1. Morphia: Simplifying Persistence for Java and MongoDB Jeff Yemin Java Evangelist, 10gen
  • 2. MongoDB on the JVM • MongoDB Java Driver – Map-based API • JVM language integrations – Casbah (Scala) – Jmongo (Ruby) – Monger (Clojure) • ODM (Object Document Mapper) – Morphia – Spring Data MongoDB
  • 3. Morphia • Object Document Mapper – Specified with annotations – Implemented with reflection • Fluent query and update APIs – Runtime validation
  • 4. Morphia by Example • Model • Test • Output
  • 5. Dependencies <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.10.1</version> </dependency> <dependency> <groupId>com.google.code.morphia</groupId> <artifactId>morphia</artifactId> <version>0.99</version> </dependency>
  • 6. Repository <repository> <id>morphia</id> <name>Morphia</name> <url>http://morphia.googlecode.com/svn/mavenrepo/</url> <layout>default</layout> </repository>
  • 7. Create the Datastore Morphia morphia = new Morphia(); Mongo mongo = new Mongo(); Datastore ds = morphia.createDatastore(mongo, "test");
  • 10. First Entity (model) class Programmer { String name; }
  • 11. First Entity (test) Programmer programmer = new Programmer(); programmer.name= "Scott Hernandez"; ds.save(programmer);
  • 12. First Entity (shell) > db.Programmer.findOne() { "_id" : ObjectId("503292d51aa814c051554696"), "className" : "demo.Programmer", "name" : "Scott Hernandez" }
  • 13. @Id (model) class Programmer { @Id ObjectId id; String name; public void toString() {…} }
  • 14. @Id (test) Programmer programmer = new Programmer(); programmer.name= "Scott Hernandez"; ds.save(programmer); System.out.println(programmer)
  • 16. String Id (model) class Programmer { @Id String githubUserName; String name; }
  • 17. String Id (test) Programmer programmer = new Programmer(); programmer.githubUserName = "scotthernandez"; programmer.name= "Scott Hernandez"; ds.save(programmer);
  • 18. String Id (shell) > db.Programmer.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : "Scott Hernandez" }
  • 19. @Entity (model) @Entity("programmers") class Programmer { @Id String githubUserName; String name; }
  • 20. @Entity (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : "Scott Hernandez" }
  • 21. More primitives (model) @Entity("programmers") class Programmer { @Id String githubUserName; String name; Date memberSince; boolean active; int followers; }
  • 22. More primitives (test) Programmer scott = new Programmer(); scott.userName = "scotthernandez"; scott.name = "Scott Hernandez"; scott.since = dateFmt.parse("Aug 12, 2009"); scott.active = true; scott.followers = 8; ds.save(scott);
  • 23. More primitives (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : "Scott Hernandez", "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "followers" : 8 }
  • 24. Primitive Array (Model) @Entity("programmers") class Programmer { @Id String githubUserName; String name; Date memberSince; boolean active; int followers; List<String> following; }
  • 25. Primitive Array (test) Programmer scott = new Programmer(); scott.userName = "scotthernandez"; scott.name = "Scott Hernandez"; scott.since = dateFmt.parse("Aug 12, 2009"); scott.active = true; scott.followers = 8; scott.following = Arrays.asList("moraes", "stickfigure"); ds.save(scott);
  • 26. Primitive Array (shell) db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : "Scott Hernandez", "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "followers" : 8, "following" : [ "moraes", "stickfigure" ] }
  • 27. @Embedded (model) @Entity("programmers") class Programmer { @Id String githubUserName; Name name; Date memberSince; boolean active; int followers; List<String> following; } @Embedded class Name { String first, last; }
  • 28. @Embedded (test) Programmer programmer = new Programmer(); programmer.githubUserName = "scotthernandez"; programmer.name = new Name("Scott", "Hernandez"); programmer.memberSince = dateFmt.parse("Aug 12, 2009"); programmer.active = true; programmer.followers = 8; programmer.following = Arrays.asList("moraes", "stickfigure"); ds.save(programmer);
  • 29. @Embedded (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "name" : { "first" : "Scott", "last" : "Hernandez" }, "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "followers" : 8, "following" : [ "moraes", "stickfigure" ] }
  • 30. @Embedded List (model) @Entity("programmers") class Programmer { @Id String githubUserName; Name name; Date memberSince; boolean active; int followers; List<String> following; List<Repository> repositories; } @Embedded class Name { String first, last; } @Embedded class Repository { String name; String forkedFrom; }
  • 31. @Embedded (test) Programmer programmer = new Programmer(); programmer.githubUserName = "scotthernandez"; programmer.name = new Name("Scott", "Hernandez"); programmer.memberSince = dateFmt.parse("Aug 12, 2009"); programmer.active = true; programmer.followers = 8; programmer.following = Arrays.asList("moraes", "stickfigure"); programmer.repositories = Arrays.asList( new Repository("docs", "mongodb/docs"), new Repository("mongo-java-driver", "mongodb/mongo-java-driver")); ds.save(programmer);
  • 32. @Embedded List (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", … "repositories" : [ { "name" : "docs", "forkedFrom" : "mongodb/docs" }, { "name" : "mongo-java-driver", "forkedFrom" : "mongodb/mongo-java-driver" } ] }
  • 33. @Reference (model) @Entity("repos") class Repository { @Id ObjectId id; @Reference Programmer owner; String name; String forkedFrom; }
  • 34. @Reference (test) Programmer programmer = new Programmer(); programmer.githubUserName = "scotthernandez"; programmer.name = new Name("Scott", "Hernandez"); programmer.memberSince = dateFmt.parse("Aug 12, 2009"); programmer.active = true; programmer.followers = 8; programmer.following = Arrays.asList("moraes", "stickfigure"); ds.save(programmer); Repository repo = new Repository(programmer, "docs", "mongodb/docs"); ds.save(repo);
  • 35. @Reference (shell) > db.repos.findOne() { "_id" : ObjectId("503297e31aa8255abe542aaa"), "className" : "demo.Repository", "owner" : DBRef("programmers", "scotthernandez"), "name" : "docs", "forkedFrom" : "mongodb/docs" }
  • 36. Small schema change (model) abstract class Member { @Id String userName; @Property("memberSince") Date since; boolean active; String name; } @Entity("programmers") class Programmer extends Member { int followers; List<String> following; } @Entity("orgs") class Organization extends Member { } @Entity("repos") class Repository { @Id ObjectId id; @Reference Member owner; String name; @Reference(lazy=true) Repository forkedFrom; }
  • 37. Small schema change (test) Programmer scott = new Programmer(); //… ds.save(scott); // save mongodb Organization Organization mongodb = new Organization("mongodb", "mongodb", sdf.parse("Jan 8, 2009")); ds.save(mongodb); // save mongodb's docs Repository Repository mongoDocs = new Repository(mongodb, "docs"); ds.save(mongoDocs); // save Scott's forked docs Repository Repository scottDocs = new Repository(scott, "docs", mongoDocs); ds.save(scottDocs);
  • 38. Small schema change (shell) > db.orgs.findOne() { "_id" : "mongodb", "className" : "demo.Organization", "memberSince" : ISODate("2009-01-08T05:00:00Z"), "active" : false, "name" : "mongodb" } > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "name" : "Scott Hernandez" … }
  • 39. Small schema change (shell, 2) > db.repos.find().toArray() [ { "_id" : ObjectId("503298be1aa8b1d255e5d45b"), "className" : "demo.Repository", "owner" : DBRef("orgs", "mongodb"), "name" : "docs" }, { "_id" : ObjectId("503298be1aa8b1d255e5d45c"), "className" : "demo.Repository", "owner" : DBRef("programmers", "scotthernandez"), "name" : "docs", "forkedFrom" : DBRef("repos", ObjectId("503298be1aa8b1d255e5d45b")) } ]
  • 41. Find by Equality (test) • ds.get(Programmer.class, "scotthernandez") • ds.find(Programmer.class, "name", "Scott Hernandez") • ds.find(Programmer.class).field("name").equal("Scott Hernandez”)
  • 42. Find by Equality (logs) • test.programmers query: { _id: "scotthernandez" } • test.programmers query: { name: "Scott Hernandez" } • test.programmers query: { name: "Scott Hernandez" }
  • 43. Find by Range (test) • ds.find(Programmer.class).field("followers").greaterThan(0) • ds.find(Programmer.class).filter("followers >", 0) • ds.find(Programmer.class).field("memberSince").lessThan(sdf.parse("Jan 1, 2010"))
  • 44. Find by Range (logs) • test.programmers query: { followers: { $gt: 0 } } • test.programmers query: { followers: { $gt: 0 } } • test.programmers query: { memberSince: { $lt: new Date(1262322000000) } }
  • 45. Combining conditions (test) ds.find(Programmer.class). field("memberSince").lessThan(dateFmt.parse("Jan 1, 2010")). field("followers").greaterThan(0)
  • 46. Combining conditions (logs) test.programmers query: { memberSince: { $lt: new Date(1262322000000) }, followers: { $gt: 0 } }
  • 47. Find by Reference (test) Programmer scott = new Programmer("scotthernandez") ds.find(Repository.class).field("owner").equal(scott)
  • 48. Find by Reference (logs) test.repos query: { owner: { $ref: "programmers", $id: "scotthernandez" } }
  • 50. @Indexed • Annotation for fields – value (IndexDirection) – name (String) – unique (boolean) – dropDups (boolean) – background (boolean) – sparse (boolean) • Examples – @Indexed(value=IndexDirection.ASC, name="followers") int followers; – @Indexed @Reference Repository forkedFrom;
  • 51. @Indexes and @Index • @Indexes: Annotation for types – value (Index[]) • @Index – value (String) – Others same as @Indexed • Examples – @Indexes(@Index("since, -followers")) public class Programmer {…}
  • 53. Updating with save (test) Programmer jeff = createJeff(); ds.save(jeff); // jeff is following scott, so increment // scott's followers and re-save Programmer scott = ds.get(Programmer.class, "scotthernandez") scott.followers++; ds.save(scott);
  • 54. Updating with save (logs) update test.programmers query: { _id: "scotthernandez", } update: { _id: "scotthernandez", className: "demo.Programmer", followers: 9, following: [ "moraes", "stickfigure" ], memberSince: new Date(1250049600000), active: true, name: "Scott Hernandez", }
  • 55. Updating with save (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "followers" : 9, "following" : [ "moraes", "stickfigure" ], "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "name" : "Scott Hernandez" }
  • 56. Optimistic Concurrency (model) @Entity public abstract class Member { @Id String userName; @Property("memberSince") Date since; boolean active; String name; @Version Long version; }
  • 57. Optimistic Concurrency (logs) update test.programmers query: { _id: "scotthernandez", version: 1345497713173 } update: { _id: "scotthernandez", className: "demo.Programmer", followers: 9, following: [ "moraes", "stickfigure" ], memberSince: new Date(1250049600000), active: true, name: "Scott Hernandez", version: 1345497718181 }
  • 58. Optimistic Concurrency (shell) > db.programmers.findOne() { "_id" : "scotthernandez", "className" : "demo.Programmer", "followers" : 9, "following" : [ "moraes", "stickfigure" ], "memberSince" : ISODate("2009-08-12T04:00:00Z"), "active" : true, "name" : "Scott Hernandez", "version" : NumberLong("1345497718181") }
  • 59. UpdateOperations (test) Programmer jeff = createJeff(); ds.save(jeff); // increment followers of scott by one UpdateOperations<Programmer> incrementFollowing = ds.createUpdateOperations(Programmer.class). inc("followers", 1); Query<Programmer> queryForScott = ds.find(Programmer.class, "_id", "scotthernandez"); ds.update(queryForScott, incrementFollowing);
  • 60. UpdateOperations (logs) update test.programmers query: { _id: "scotthernandez" } update: { $inc: { followers: 1 } }
  • 61. Web Resources • Morphia home: http://code.google.com/p/morphia/ • Morphia user group: https://groups.google.com/forum/?fromgroups#!forum/morphia • Demo code: https://github.com/jyemin/morphia-demo – Separate commit and tag for each slide, so you can play along
  • 62. Thanks! • Jeff Yemin – https://twitter.com/@jeffyemin – jeff.yemin@10gen.com – https://github.com/jyemin/

Editor's Notes

  1. Builds on the java driver&quot;test&quot; is the name of a database&apos;
  2. NameEmilMember SinceFollowersRespositories
  3. No annotations. Pure POJO
  4. 1. Save will insert or update
  5. Collection name defaults to class name_id is generated as an ObjectIdclassName has the full class name, including package. Used for polymorphic collectionCan you query for base class? How?
  6. 1. Morphia will generate an id and stuff it in the field annotated with @Id
  7. 1. If you already have a unique id, you should use it as your @Id
  8. 1. Morphia won&apos;t generate these for you
  9. 1. If you just use @Entity, it defaults the collection name to the class name.
  10. Note the collection name
  11. Let&apos;s switch it up. Instead of embedding the repos in the programmer, let&apos;s have repos as top-level docs that reference owner by key
  12. Get by primary keyShortcut for getting by a single propertyLongcut, same as above but extensible
  13. 1. Note the weird syntax to make followers descending
  14. Note that to update followers, we updated everything…Point out the problems with this