Introduction to RavenDB

  • 655 views
Uploaded on

Presentation from SDP 2014 covering RavenDB - the .NET document database. Discussing basic CRUD operations, indexes, and full-text search.

Presentation from SDP 2014 covering RavenDB - the .NET document database. Discussing basic CRUD operations, indexes, and full-text search.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
655
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
11
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • © 2013 Visual Studio Live! All rights reserved.

Transcript

  • 1. © Copyright SELA software & Education Labs Ltd. | 14-18 Baruch Hirsch St Bnei Brak, 51202 Israel | www.selagroup.com SELA DEVELOPER PRACTICE JUNE 29 – JULY 3, 2014 Sasha Goldshtein blog.sashag.net CTO, Sela Group @goldshtn Introduction to RavenDB
  • 2. NoSQL The Zen-like answer: No one can tell you what NoSQL is, they can only tell you what it isn’t It doesn’t use SQL It usually is less consistent than RDBMS It doesn’t put an emphasis on relations It emphasizes size and scale over structure
  • 3. Classes of NoSQL Databases Document DB Key- Value DB Graph DB Column DB
  • 4. RavenDB Transactional document database Open source https://github.com/ravendb/ravendb with licensing for commercial projects Schema-less documents, JSON storage RESTful endpoints LINQ-style .NET API Implicit (usage-based) or explicit indexing Powerful text search based on Lucene Replication and sharding support Oren Eini (Ayende Rahien)
  • 5. Hosting RavenDB Raven.Server.exe Windows Service Integrated in IIS Embedded client for stand-alone apps Cloud-hosted (e.g. RavenHQ)
  • 6. Management Studio
  • 7. Demo RavenDB Management Studio
  • 8. Opening a Session DocumentStore is the session factory; one per application is enough Supports .NET connection strings or direct initialization: var ds = new DocumentStore { Url = "http://localhost:8888" }; ds.Initialize();
  • 9. CRUD Operations on Documents using (var session = documentStore.OpenSession()) { session.Store(new Speaker(“Sasha”, “Jerusalem”)); session.SaveChanges(); } using (var session = documentStore.OpenSession()) { Speaker sasha = session.Query<Speaker>() .Where(e => e.City == “Jerusalem”).First(); sasha.City = “Tel-Aviv”; session.SaveChanges(); }
  • 10. Collections and IDs Documents are stored in JSON format Documents have metadata that includes the entity type A collection is a set of documents with the same entity type Documents have unique ids, often a combination of collection name + id speakers/1 conferences/7
  • 11. Demo Basic Operations
  • 12. Modeling Data as Documents Don’t be tempted to use a document store like a relational database Documents should be aggregate roots References to other documents are OK but (some) data duplication (denormalization) is also OK “conference/11” : { tracks: [ { title: “Web”, days: { 1, 2 }, sessions: [ ... ] }, ... ] } Should the tracks be references?
  • 13. …But Don’t Go Too Far Is this a reasonable document? “blogs/1” : { tags : [ “Windows”, “Visual Studio”, “VSLive” ], posts : [ { title: “Migrating to RavenDB”, content: “When planning a migration to Raven…”, author: “Sasha Goldshtein”, comments: [ ... ] }, ... ] } My blog has 500 posts
  • 14. One More Example “orders/1783”: { customer: { name: “James Bond”, id: “customers/007” }, items: [ { product: “Disintegrator”, cost: 78.3, qty: 1 }, { product: “Laser shark”, cost: 99.0, qty: 3 } ] } What if we always need the customer’s address? What if the customer’s address changes often? What if we always need to know whether the product is in stock?
  • 15. Include Load the referenced document when the referencing document is retrieved Also supports arrays of referenced documents Order order = session.Include<Order>(o => o.Customer.Id) .Load(“orders/1783”); Customer customer = session.Load<Customer>( order.Customer.Id); Order[] orders = session.Query<Order>() .Customize(q => q.Include<Order>(o => o.Customer.Id)) .Where(o => o.Items.Length > 5) .ToArray();
  • 16. Demo Include and Load
  • 17. Indexes RavenDB automatically creates indexes for you as you run your queries The indexing happens in the background Indexes can become stale Can wait for non-stale results (if necessary) RavenQueryStatistics stats; var results = session.Query<Speaker>() .Statistics(out stats) .Where(s => s.Experience > 3) .ToArray(); if (stats.IsStale) ...
  • 18. ACID? If indexes can become stale, does it mean RavenDB is not ACID? The document store is ACID The index store is not You can insert lots of data very quickly and load it quickly, but indexes take a while to catch up
  • 19. Indexing Fundamentals A document has fields that are indexed individually An index points from sorted field values to matching documents "orders/1" : { customer: "Dave", price: 200, items: 3 } "orders/2" : { customer: "Mike", price: 95, items: 1 } "orders/3" : { customer: "Dave", price: 150, items: 2 } Customer Document IDs Dave orders/1, orders/3 Mike orders/2 PriceRange Document IDs 0-99 orders/2 100-199 orders/3 200-299 orders/1
  • 20. Static (Manual) Indexes Static indexes can provide map and reduce functions to specify what to index The simplest form specifies a map function with the fields to index: ds.DatabaseCommands.PutIndex(“Speaker/ByCity”, new IndexDefinitionBuilder<Speaker> { Map = speakers => from speaker in speakers select new { speaker.City } } );
  • 21. Map/Reduce Index We often need the speaker count for each of our conferences: ds.DatabaseCommands.PutIndex(“Conferences/SpeakerCount”, new IndexDefinitionBuilder<Conference, SpeakerCount> { Map = conferences => from conf in conferences from speaker in conf.Speakers select new { Item1 = speaker.Name, Item2 = 1 }, Reduce = results => from result in results group result by result.Item1 into g select new { Item1 = g.Key, Item2 = g.Sum(x => x.Item2) } } ); class SpeakerCount : Tuple<string, int> {}
  • 22. Using Indexes In most cases you simply run a query and it will implicitly use or create an index Or, instruct the query to use your index: var d = session.Query<SpeakerCount>(“Conferences/SpeakerCount”) .FirstOrDefault(s => s.Item1 == “Dave”); Console.WriteLine(“Dave spoke at {0} conferences”, d.Item2); var posts = session.Query<Comment>(“CommentsIndex”) .Where(c => c.Author == “Mike”) .OfType<Post>();
  • 23. Demo Using Indexes
  • 24. Full-Text Search Indexes Made possible by the underlying Lucene.NET engine public class SpeakerIndex : AbstractIndexCreationTask<Speaker> { public SpeakerIndex() { Map = speakers => from speaker in speakers select new { speaker.Name }; Index("Name", FieldIndexing.Analyzed); } }
  • 25. Using Full-Text Search and Query Suggestions var query = session.Query<Speaker, SpeakerIndex>() .Where(s => s.Name == name); var speaker = query.FirstOrDefault(); if (speaker == null) { string[] suggestions = query.Suggest().Suggestions; } Will find “Dave Smith” when searching for “dave” or “smith” Will suggest “dave” when searching for “david”
  • 26. Using Lucene Directly You can also query Lucene directly on any analyzed fields E.g., fuzzy search for sessions: string query = String.Format("Title:{0}*", term); session.Advanced.LuceneQuery<Session>("SessionIndex") .Where(query) .ToList();
  • 27. Demo Full-Text Search and Suggestions
  • 28. Advanced Features Batch operations by index Async API (OpenAsyncSession, await) Attachments Patching (partial document updates) Change notifications (IDatabaseChanges) Transactions (TransactionScope) …and many others http://ravendb.net/docs
  • 29. Upcoming Features in RavenDB 3.0 Management Studio rewrite in HTML5 Web API-based infrastructure First-class Java client SDK Custom storage engine (Voron)
  • 30. © Copyright SELA software & Education Labs Ltd. | 14-18 Baruch Hirsch St Bnei Brak, 51202 Israel | www.selagroup.com SELA DEVELOPER PRACTICE JUNE 29 – JULY 3, 2014 Thank You! Sasha Goldshtein @goldshtn blog.sashag.net