LiteDB - Embedded NoSQL database
Wed, Jan 25, 2017As the title states - LiteDB is embedded nosql one file database. In terms of features it offers quite a lot:
- LINQ support
- ACID transactions
- Custom mapping
- Data streaming
- Thread safe (from version 3)
- Excellent performance
LiteDB is written in C#, so there is not much effort needed to integrate it into your project - just add it from nuget by running
Install-Package LiteDB
Without further ado, let’s write some code. First we need to create our model:
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
}
Important note here
If you are interacting with LiteDB via POCOs, LiteDB automatically converts them to the internal BsonDocument type. Because of that automation, there are some rules, that you have to follow. You can find them all in the documentation. The main ones are:
- parameterless constructor
- Id property (or property decorated with [BsonId] attribute)
Connecting to/creating database
For the demo purposes I’m going to use this helper method to simplify the code. In real application you would definitely hide your database behind some kind of abstraction and parameterize the connection string.
LiteDatabase OpenDatabase()
{
var connectionString = "sample.db";
var db = new LiteDatabase(connectionString);
return db;
}
Simplest connection string is just the path to the database file. If the file doesn’t exist, it will be created upon the first write.
How to do basic CRUD
Now to actually do something useful …
Adding items to the database
var products = new List<Product>
{
new Product
{
Id = Guid.NewGuid(),
Name = "Potato",
Description = "The finest potato you can get",
Price = 12.30m
},
new Product
{
Id = Guid.NewGuid(),
Name = "Bread",
Description = "Not just flour and water",
Price = 15.40m
},
new Product
{
Id = Guid.NewGuid(),
Name = "Butter",
Description = "Smooth and delicious butter",
Price = 9.50m
}
};
using (var db = OpenDatabase())
{
var collectionName = nameof(Product);
var productsDb = db.GetCollection<Product>(collectionName);
var insertedCount = productsDb.Insert(products);
var totalCount = productsDb.Count();
Console.WriteLine($"inserted: { insertedCount }; total: { totalCount }");
// which outputs: inserted: 3; total: 3
}
Since this is a nosql database, we are working with collections of documents. The method call GetCollection opens a collection with the specified name. If the collection doesn’t exist, it will be created for us (on the first write).
Transactions
If you don’t explicitly open a transaction, it is automatically opened for each command. Calling the Commit method will write all changes to disk.
Querying data
Let’s do a simple query to find all products with a price lower than 15
using (var db = OpenDatabase())
{
var collectionName = nameof(Product);
var productsDb = db.GetCollection<Product>(collectionName);
var products = productsDb.Find(p => p.Price < 15);
}
As a side note - LiteDB needs to have the property on which you search indexed. So if it’s not indexed, it will create an index on the fly. But you can then always drop it with the DropIndex method.
Updating
using (var db = OpenDatabase())
{
var collectionName = nameof(Product);
var productsDb = db.GetCollection<Product>(collectionName);
// find the item
var productToUpdate = productsDb.Find(p => p.Name == "Butter").First();
// change some properties
productToUpdate.Price = 3.50m;
// write back changes
productsDb.Update(productToUpdate);
}
Deleting
using (var db = OpenDatabase())
{
var collectionName = nameof(Product);
var productsDb = db.GetCollection<Product>(collectionName);
var productToDelete = productsDb.Find(p => p.Name == "Bread").First();
productsDb.Delete(productToDelete.Id);
}
For more information and examples check out the docs.