在单个数据文件中,LiteDB. NET NoSQL 文档存储

分享于 

17分钟阅读

数据库

  繁體 雙語

介绍

本篇文章介绍我的数据库项目 LiteDB - 一个小型。快速。免费的嵌入式文档存储文档存储在一个文件中,现在它是一个新版本,收费为

/上提供了更多的示例和在线 shell,源代码位于GitHub或者下载二进制文档完整文档位于 GitHub Wiki页面。

功能

  • 无服务器 NoSQL 文档存储
  • 简单的API与MongoDB官方驱动程序非常类似
  • 100% C# 代码,用于单个 DLL ( 小于 200 kb ) 中的.NET 3.5 - 无相关性
  • 支持便携式平台:.NET,UWP 8.1/10, Xarmin iOS和 Android
  • 事务处理控制- ACID
  • 写入失败( 日志模式)
  • 对POCO类或者BsonDocument的支持
  • 使用DES加密的加密数据文件
  • 用于文件和流数据( 如MongoDB中的GridFS )的FileStorage
  • 单个数据文件存储( 如 SQLite )
  • 用于快速搜索的索引文档字段( 每个集合最多可以有 16个索引)
  • LINQ对查询的支持
  • shell 命令行 ( 试用这里在线版本 )
  • 开源和免费为所有人- 包括商业使用
  • 从NuGet安装:安装软件包 LiteDB 或者安装包 LiteDB.Core ( 用于便携式)

v2.0中的新增内容

  • 抽象层- 现在你的数据文件可以是任何流或者你可以实现你自己的持久层。
  • 使用一个流畅的API映射你的实体类,如 Entity Framework
  • 跨实体关系( 交叉引用)的更好解决方案: 你的域类与LiteDB实现完全分离。
  • 新的清理缓存系统。在大型事务(。使用日志文件) 中避免过多的内存使用。
  • 支持初始数据库大小和最大数据库大小
  • 使用DES加密加密数据文件
  • 延迟加载 - 仅在数据访问时打开数据文件。
  • 更好地支持并发写入
  • 收缩数据文件
  • 数据库日志信息

LiteDB对MongoDB有很大的启发。 我试图创建一个与MongoDB一样工作的数据库,但在很小的范围内只使用了最重要的。 如果你知道 MongoDB,你已经知道了 LiteDB。

如何使用

存储和搜索文档的快速示例:

// Open data file (or create if not exits)using(var db = new LiteDatabase(@"C:TempMyData.db"))
{
 // Get customer collectionvar col = db.GetCollection<Customer>("customers");
 var customer = new Customer { Id = 1, Name = "John Doe" };
 // Insert new customer document col.Insert(customer);
 // Update a document inside a collection customer.Name = "Joana Doe";
 col.Update(customer);
 // Index document using a document property col.EnsureIndex(x => x.Name);
 // Simple Linq supportvar result = col.Find(x => x.Name.StartsWith("Jo"));
}

在哪里使用?

  • 小型网络应用,站点博客或者 foruns
  • 每英镑帐户/用户数据存储中的一个数据存储
  • 桌面/局部小型应用程序
  • 应用程序文件格式
  • 很少并发写入用户操作

快速启动

如果你需要更多文档,可以阅读文档。

文稿

LiteDB使用文档在数据文件中存储和检索数据。 文档定义可以是一个POCO类或者BsonDocument类。 在这两种情况下,LiteDB将以BSON格式转换你的文档以存储在磁盘内。

BSON是二进制 JSON,它是作为二进制 array 存储数据对象的序列化。 在BSON中,我们有比JSON更多的数据类型,比如日期时间。Guid和 ObjectId。

使用POCO类的文档

POCO类是只使用获取/设置属性的简单 C# 类。 这是创建强类型文档的最佳方法。 你的类必须具有标识符属性。 你可以使用 Id named命名属性,<类名> 或者装饰任何具有 [BsonId] 属性的属性。

// A poco entity, must have Idpublicclass Customer
{
 publicint Id { get; set; }
 publicstring Name { get; set; }
 public List<Phone> Phones { get; set; }
}// It's not a entity, don't need Idpublicclass Phone
{
 publicint Code { get; set; }
 publicstring Number { get; set; }
 public PhoneType Type { get; set; }
}publicenum PhoneType { Mobile, Landline } 
  • 内部,文档id表示为" _id"属性
  • 不要使用复杂的数据类型( 如数据集,DataTable )
  • 不要使用一次性对象( 如流图形
  • 序列化时,枚举将在字符串中转换
  • 你的标识值必须是唯一的而不是空
  • 如果你将 Id 留空,LiteDB将自动生成插入。

映射器约定

BsonMapper.ToDocument() 自动将文档字段中的每个属性类转换为以下约定:

  • 类必须是带有 public 非参数构造函数的public
  • 属性必须为 public
  • 属性只能读取或者读取/写入
  • 类必须具有Id属性。<ClassName> Id属性或者任何具有 [BsonId] 属性的属性才能存储标识信息
  • 属性可以用 [BsonIgnore] 修饰,不能映射到文档
  • 属性可以用 [BsonField] 装饰,以具有自定义名称字段
  • 不允许循环引用
  • 20深度内部类的最大值
  • 类字段不转换为文档
  • BsonMapper使用全局实例来缓存映射信息以获得更好的性能。 这里实例在 LiteDatabase.Mapper 属性上。

用于文档映射的API

如果希望更改默认的约定映射,则可以使用EntityBuilder将实体类映射到 BsonDocument。

var mapper = BsonMapper.Global;
mapper.Entity<Customer>()
. Id(x => x.CustomerKey)
. Field(x => x.Name, "customer_name")
. Ignore(x => x.Age)
. Index(x => x.Name, unique);

跨文档集合引用的DbRef

LiteDB可以使用交叉文档refereces只使用 _id 值( 不嵌入孔子文档) 映射内部实体。

// Your entity order class publicclass Order
{
 publicint OrderId { get; set; }
 public Customer Customer { get; set; }
}
​​​// Map Customer property to"customers" collections BsonMapper.Global.Entity<Order>()
. DbRef(x => x.Customer, "customers"); // When insert an order, only customer _id will be included as reference// Get orders collectionvar orders = db.GetCollection<Order>("orders");// Find an order including Customer referencevar order = orders
. Include(x => x.Customer)
. FindById(123);

LiteDB将序列化 Order 文档为` { _id: 123, Customer: { $id:1, $ref:"customers" } }` 当需要包含客户实例的查询顺序时,只需在运行查找方法之前添加。

使用BsonDocument的文档

BsonDocument 是一个特殊类,它使用内部收费字典 <字符串( 对象> ) 映射任何文档。 读取未知文档类型或者用作通用文档非常有用。

// Create a BsonDocument for Customer with phonesvar doc = new BsonDocument();
doc["_id"] = ObjectId.NewObjectId();
doc["Name"] = "John Doe";
doc["Phones"] = new BsonArray();
doc["Phones"].Add(new BsonObject());
doc["Phones"][0]["Code"] = 55;
doc["Phones"][0]["Number"] = "(51) 8000-1234";
doc["Phones"][0]["Type"] = "Mobile";

使用 BsonDocument,你可以创建任何复杂的文档模式。

收藏- 商店

LiteDB组织存储中的文档( 在LiteDB中作为集合调用)。 每个集合都具有唯一的名称,并且包含具有相同架构/类型的文档。 你可以从LiteDatabase实例中使用GetCollection获得强类型集合或者通用BsonDocument集合。

var db = new LiteDatabase(stringConnection);// Get a strong typed collectionvar customers = db.GetCollection<Customer>("Customers");// Get a BsonDocument collection var customers = db.GetCollection("Customers");

集合包含操作文档的所有方法:

  • 插入插入新文档
  • 使用查询对象或者LINQ表达式查找 document 找到 document FindOne FindOne Find Find。 此时,只支持简单的LINQ - 左边的属性,右侧的值。
  • 更新 - 更新文档
  • 删除 - Delete 文档id或者使用查询
  • 包括 - 使用包含来根据其他集合填充属性
  • EnsureIndex - 如果不存在则创建索引。 所有查询都必须有索引。

查询

在LiteDB中,查询使用索引来查找文档。 你可以使用查询 helper 或者Linq表达式。

var customers = db.GetCollection<Customer>("customers");// Create a new index (if not exists)customers.EnsureIndex("Name");// Query documents using 'Name' indexvar results = customers.Find(Query.StartsWith("Name", "John"));// Or using Linqvar results = customers.Find(x => x.Name.StartsWith("John"));// Return document by ID (PK index)var customer = customers.FindById(1);// Count documents using Query helpervar count = customers.Count(Query.GTE("Age", 22));// All query results returns an IEnumerable<T>, so you can use Linq in resultsvar results = customers
. Find(x => x.Name.StartsWith("John") && x.Salary >500) // two indexed queries. Where(x => x.LastName.Length >5) // in memory query. Select(x =>new { x.Name, x.Salary })
. OrderBy(x => x.Name);

类的所有属性,如,英镑,英镑,英镑,英镑,英镑,英镑,英镑,英镑,英镑,英镑,英镑,英镑,英镑。

容错- 日志/恢复

LiteDB在磁盘日志文件中使用以保证写入操作的持久性。 这意味着在写操作之前,所有脏页首先在separeted文件中编写,然后再写入主文件。

在连接字符串上可以禁用这里功能- 运行更快但是如果写入操作失败,数据文件不一致。

使用文件- FileStorage

Sametimes我们需要在数据库中存储文件。 为此,LiteDB有一个特殊的FileStorage 集合,用于存储文件,而无需文档大小限制( 文件限制为每个文件 2Gb )。 它的工作方式是 MongoDB

// Storing a file stream inside databasedb.FileStorage.Upload("my_key.png", stream);// Get file reference using file idvar file = db.FileStorage.FindById("my_key.png");// Find all files using StartsWithvar files = db.Files.Find("my_");// Get file streamvar stream = file.OpenRead();// Write file stream in a external streamdb.FileStorage.Download("my_key.png", stream);

LiteDB创建 2个集合来处理文件: _files_chunks. 集合 _files 包含文件信息( 文件 id,文件名,上传日期和元数据)。 文件数据内容在 _chunks 集合中为 splited。

LiteDB.Shell

LiteDB包含一个 shell 控制台应用程序。 这里 shell 可以用于在数据文件中运行命令而无需任何其他应用程序。 查看以下最有用的命令。 若要查看所有命令,请使用"帮助"命令。

Shell commands==============
> open <filename|connectionString> : Open a new database
> pretty on|off : Turns on/off pretty json format
> timer : Show timer before prompt> dump> <dumpfile.dmp> : Export database as insert commands> dump <<dumpfile.dmp> : Import databaseCollections commands====================
> db.<collection>.insert <jsonDoc> : Insert a new document into collection
> db.<collection>.update <jsonDoc> : Update a document inside collection
> db.<collection>.delete <filter> : Delete documents using a filter clausule (see find)
> db.<collection>.find [top N] <filter> : Show filtered documents based on index search
> db.<collection>.count <filter> : Show count rows according query filter
> db.<collection>.ensureIndex <field> [unique] : Create a new index document field
> db.<collection>.drop : Drop collection and destroy all documents inside
<filter> = <field> [=|>|>=|<|<=|!=|like|contains|between] <jsonValue> : Filter query syntax
<filter> = (<filter> [and|or] <filter> [and|or].. .) : Multi queries syntax
<jsonDoc> = {_id:.. ., key: value, key1: value1 } : Represent an extended json for a BsonDocument.File storage commands=====================
> fs.find : List all files on datafile
> fs.find <fileId> : List file info from a key. Supports * for starts with key
> fs.upload <fileId> <filename> : Insert a new file inside database
> fs.download <fileId> <filename> : Save a file to disk passing a file key and filename
> fs.update <fileId> {key:value} : Update metadata file
> fs.delete <fileId> : Remove a file inside database

历史记录

  • 更新 v2.0.0 - 1 Ago 2016
    • 支持便携式- UWP,Xamarin - iOS和安卓
    • .NET 3.5
    • 新磁盘访问避免锁定功能: 仅使用读/写独占模式
    • 添加一些v1功能: 用户事务控制,register autoId和全局映射器实例
  • 更新 v.2. 0.0-rc - 24 2015年月
    • 加密数据文件
    • 数据文件从 v0.9.0/v1.0.x 迁移
    • 将数据文件转储为插入
    • 更好的缓存/并发支持
    • ( 圣诞节)
  • 更新 v.2. 0.0-beta - 27 2015年月
    • 抽象持久层
    • Fluent映射器 API
    • 新建 DbRef
    • 虚拟索引字段
    • 新的清理缓存系统
    • 用于初始数据库大小和最大数据库大小的Suport
    • 延迟加载。
    • ThreadSafe和 ProcessSafe
    • 收缩数据文件
    • 数据库日志信息
  • 更新 v1.0.2 - 17 2015年05月
    • 在文档中使用_type字段( 在MongoDB中使用) 对接口和基类进行BsonMapper序列化/反序列化
    • 用于NameValueCollection的BsonMapper
    • 增加了对布尔Linq操作的支持,如x => x.IsActive
    • 修正了字符串索引更新/删除操作
    • 删除全部扫描文档查找操作- 现在只使用索引工作
    • 如果不存在自动创建索引
  • 更新 v1.0 - 28 2015年03月
    • 新BsonSerializer删除fastBinaryJson并实现真正的BSON规范
    • 新增BsonMapper可以从/到BsonDocument获得更多可以配置的POCO
    • 新JsonReader实现:无 正规表达式 和 4倍
    • 标识文档中使用的新 ObjectId
    • 索引创建选项- 删除空白,删除重音,忽略大小写
    • [BsonIndex] 属性将实体属性标记为在查询时自动创建索引
    • 实体标识属性的自动生成 Id
    • 可以在没有索引的情况下执行 Find() ( 将执行完整的文档扫描)
    • FindAll() 支持上升/递减结果
    • 新建 Query.Contains
    • 索引中的最小( )/最大( ) 值
    • DbRef <> - 一个用于参考文档的简单类
    • 删除收集和删除索引改进
    • 删除_master集合- 避免 1页读取
  • 更新 v0.9 - 07 2015年02月
    • 添加 MongoDB banchmark
    • 添加 shell 快速浏览
  • 初始版本 - 25 2015年01月

数据  文件  DOC  Store  SIN  Nosql  
相关文章