Node.js/NW.js的持久化数据库:LinvoDB

jopen 10年前

Node.js/NW.js的持久化数据库,拥有类似MongoDB/Mongoose的功能和接口构建在 LevelUp 之上。
</div>

特性:

  • 类似MongoDB的查询引擎
  • 构建在LevelUP之上的持久化,你可以选择不同的后端
  • NW.js 友好- JS唯一后端是 Medea
  • 性能 - 稳定的性能不受数据库大小 - 查询总是索引
  • 自动索引
  • 实时查询 - 使查询,得到持续最新的结果
  • Schemas - built-in schema support
  • Efficient Map / Reduce / Limit

与NeDB的关系

LinvoDB 是构建在 NeDB 之上,最显著核心的变化是,它使用的LevelUp作为后端。 meaning it doesn't have to keep the whole dataset in memory. LinvoDB also can do a query entirely by indexes, meaning it doesn't have to scan the full database on a query.

In general:

  • LinvoDB is better for large datasets (many objects, or large objects) because it doesn't keep the whole DB in memory and doesn't need to always scan it
  • LinvoDB does the entire query through the indexes, NeDB scans the DB
  • Both LinvoDB and NeDB play well with NW.js (node-webkit). LinvoDB can be initialized with the JS-only MedeaDown back-end.
  • NeDB is ultra-fast because the DB is in memory, LinvoDB's performance is comparible to MongoDB
  • LinvoDB has live queries, map/reduce and schema support.

Install, Initialize, pick backend

Install:

npm install linvodb3 medeadown # For NW.js, using Medea  npm install leveldb3 leveldown # For pure node.js, using LevelDB

Initialize:

var LinvoDB = require("linvodb3");  LinvoDB.defaults.store = { db: require("medeadown") }; // Comment out to use LevelDB instead of Medea    var Doc = new LinvoDB("doc", { /* schema, can be empty */ })


Initialization, detailed:

var LinvoDB = require("linvodb3");  var modelName = "doc";  var schema = { }; // Non-strict always, can be left empty  var options = { };  // options.filename = "./test.db"; // Path to database - not necessary   // options.store = { db: require("medeadown") }; // Options passed to LevelUP constructor   var Doc = new LinvoDB(modelName, schema, options); // New model; Doc is the constructor    LinvoDB.dbPath // default path where data files are stored for each model  LinvoDB.defaults // default options for every model


插入、保存

The native types areString,Number,Boolean,Dateandnull. You can also use arrays and subdocuments (objects). If a field isundefined, it will not be saved.

If the document does not contain an_idfield, one will be automatically generated (a 16-characters alphanumerical string). The_idof a document, once set, cannot be modified.

// Construct a single document and then save it  var doc = new Doc({ a: 5, now: new Date(), test: "this is a string" });  doc.b = 13; // you can modify the doc   doc.save(function(err) {       // Document is saved      console.log(doc._id);  });    // Insert document(s)  // you can use the .insert method to insert one or more documents  Doc.insert({ a: 3 }, function (err, newDoc) {      console.log(newDoc._id);  });  Doc.insert([{ a: 3 }, { a: 42 }], function (err, newDocs) {      // Two documents were inserted in the database      // newDocs is an array with these documents, augmented with their _id        // If there's an unique constraint on 'a', this will fail, and no changes will be made to the DB      // err is a 'uniqueViolated' error  });    // Save document(s)  // save is like an insert, except it allows saving existing document too  Doc.save([ doc, { a: 55, test: ".save is handy" } ], function(err, docs) {       // docs[0] is doc      // docs[1] is newly-inserted document with a=55 and has an assigned _id        // Doing that with .insert would throw an uniqueViolated error for _id on doc, because it assumes all documents are new  });


查询

Usefindto look for multiple documents matching you query, orfindOneto look for one specific document. You can select documents based on field equality or use comparison operators ($lt,$lte,$gt,$gte,$in,$nin,$ne,$regex,$exists). You can also use logical operators$or,$andand$not. See below for the syntax.

var Planet = new LinvoDB("planet", { /* schema, can be empty */ })    // Let's say our datastore contains the following collection  Planet.save([       { _id: 'id1', planet: 'Mars', system: 'solar', inhabited: false, satellites: ['Phobos', 'Deimos'] },      { _id: 'id2', planet: 'Earth', system: 'solar', inhabited: true, humans: { genders: 2, eyes: true } },      { _id: 'id3', planet: 'Jupiter', system: 'solar', inhabited: false },      { _id: 'id4', planet: 'Omicron Persei 8', system: 'futurama', inhabited: true, humans: { genders: 7 } },      { _id: 'id5', completeData: { planets: [ { name: 'Earth', number: 3 }, { name: 'Mars', number: 2 }, { name: 'Pluton', number: 9 } ] } }  ], function() {     // Finding all planets in the solar system  Planet.find({ system: 'solar' }, function (err, docs) {    // docs is an array containing documents Mars, Earth, Jupiter    // If no document is found, docs is equal to []  });    // Finding all inhabited planets in the solar system  Planet.find({ system: 'solar', inhabited: true }, function (err, docs) {    // docs is an array containing document Earth only  });    // Use the dot-notation to match fields in subdocuments  Planet.find({ "humans.genders": 2 }, function (err, docs) {    // docs contains Earth  });    // Use the dot-notation to navigate arrays of subdocuments  Planet.find({ "completeData.planets.name": "Mars" }, function (err, docs) {    // docs contains document 5  });    Planet.find({ "completeData.planets.0.name": "Earth" }, function (err, docs) {    // docs contains document 5    // If we had tested against "Mars" docs would be empty because we are matching against a specific array element  });    // You can also deep-compare objects. Don't confuse this with dot-notation!  Planet.find({ humans: { genders: 2 } }, function (err, docs) {    // docs is empty, because { genders: 2 } is not equal to { genders: 2, eyes: true }  });    // Find all documents in the collection  Planet.find({}, function (err, docs) {  });    // The same rules apply when you want to only find one document  Planet.findOne({ _id: 'id1' }, function (err, doc) {    // doc is the document Mars    // If no document is found, doc is null  });      }); // end of .save()

项目主页:http://www.open-open.com/lib/view/home/1425800554753