lokijs可以用mysql_loki 数据库详解
介紹
LokiJS是一個(gè)面向文檔的javascript數(shù)據(jù)庫,與MongoDB有點(diǎn)相似。
它支持索引,查詢和過濾數(shù)據(jù)集合。 LokiJS還支持更高級(jí)的功能,例如mapReduce,事務(wù),并允許您實(shí)現(xiàn)自定義遠(yuǎn)程同步以將數(shù)據(jù)保存到服務(wù)器(或移動(dòng)設(shè)備上的本地文件)。
磁盤的持久性已經(jīng)在諸如nodejs之類的CommonJS環(huán)境中實(shí)現(xiàn),
在移動(dòng)設(shè)備上,您只需要請求文件系統(tǒng)并將lokijs的serialize()作為內(nèi)容傳遞即可。
創(chuàng)建
創(chuàng)建一個(gè) db:var db = new loki('Example');
除了 Example 這個(gè)數(shù)據(jù)庫的名稱外, 還可以傳遞一個(gè)選項(xiàng)參數(shù):interface LokiConfigOptions {
adapter: LokiPersistenceAdapter | null;
autoload: boolean;
autoloadCallback: (err: any) => void;
autosave: boolean;
autosaveCallback: (err?: any) => void;
autosaveInterval: string | number;
persistenceMethod: "fs" | "localStorage" | "memory" | null;
destructureDelimiter: string;
serializationMethod: "normal" | "pretty" | "destructured" | null;
throttledSaves: boolean;
}
關(guān)于參數(shù): persistenceMethod 需要注意的點(diǎn):"fs": 只能在 node 環(huán)境中使用(包括 electron)
"localStorage" : web 中可以使用,并且數(shù)據(jù)會(huì)存在 localStorage 中,進(jìn)行持久存儲(chǔ)
"memory": 只是簡單的存在內(nèi)容中,如果刷新頁面,數(shù)據(jù)就不存在了
在不同的環(huán)境中, 他創(chuàng)建的持久層是不同的, 比如
在瀏覽器中, 是基于 web 數(shù)據(jù)庫或者 localStorage(默認(rèn)) 的
在 node 環(huán)境中, 可以基于 fs, 創(chuàng)建文件數(shù)據(jù)庫
關(guān)于他們的變化是需要一個(gè) option.adapter 來進(jìn)行協(xié)助
在 web 中, 如果想要將數(shù)據(jù)存到 web 數(shù)據(jù)庫中,
那么就需要 option.adapter 了(當(dāng)傳遞了 adapter 參數(shù)時(shí), 'persistenceMethod' 參數(shù)就會(huì)被無效)
但是如果使用了 option.adapter,那么只能使用自動(dòng)加載數(shù)據(jù)庫和字段保存數(shù)據(jù)庫的方案
增加數(shù)據(jù)
針對 loki 里的 Collection 如果了解數(shù)據(jù)庫,可以將它當(dāng)成 表 這種結(jié)構(gòu)
想要添加數(shù)據(jù),需要先獲取 collection 對象
可以在添加 collection 的時(shí)候獲取:const users = db.addCollection('users', {indices: ['email']});
可以直接獲取:const coll = db.getCollection('users')
注意 addCollection 有 2 個(gè)參數(shù)可以傳遞:第一個(gè)參數(shù)是 name 是 collection 的名稱
第二個(gè)是可選項(xiàng)參數(shù),它擁有很多參數(shù):名稱類型屬性默認(rèn)值描述unique數(shù)組[]屬性名稱數(shù)組,用于定義唯一約束
exact數(shù)組[]屬性名稱數(shù)組,用于定義確切的約束
indices數(shù)組[]用于定義二進(jìn)制索引的數(shù)組屬性名稱
adaptiveBinaryIndices布爾值true收集索引將被重新建立而不是懶加載
asyncListeners布爾值false偵聽器是否異步調(diào)用
disableMeta布爾值false設(shè)置為true以禁用文檔的元屬性
disableChangesApi布爾值true設(shè)置為false以啟用Changes API
disableDeltaChangesApi布爾值true設(shè)置為false以啟用Delta更改API(需要更改API,強(qiáng)制克隆)
autoupdate布爾值false使用Object.observe自動(dòng)更新對象
clone布爾值false指定是否向用戶插入或從用戶克隆查詢
serializableIndices布爾值true[]將二進(jìn)制索引屬性上的日期值轉(zhuǎn)換為紀(jì)元時(shí)間
cloneMethod字符串'parse-stringify''parse-stringify', 'jquery-extend-deep', 'shallow', 'shallow-assign'
ttlint文件被認(rèn)為是陳舊/過時(shí)之前的文件時(shí)間(以毫秒為單位)。
ttlIntervalint清除“陳舊”文件的時(shí)間間隔;默認(rèn)情況下未設(shè)置。
使用 inert 添加數(shù)據(jù)const coll = db.getCollection('users')
var odin = users.insert({name: 'odin', email: 'odin.soap@lokijs.org', age: 38});
var thor = users.insert({name: 'thor', email: 'thor.soap@lokijs.org', age: 25});
var stan = users.insert({name: 'stan', email: 'stan.soap@lokijs.org', age: 29});
// 也可以同時(shí)插入多個(gè)數(shù)據(jù)
// users.insert([{ name: 'Thor', age: 35}, { name: 'Loki', age: 30}]);
這里要注意的是: 分清楚數(shù)據(jù)的存儲(chǔ)狀態(tài), 當(dāng)我們不使用自動(dòng)保存和手動(dòng)保存的時(shí)候 insert, 會(huì)將數(shù)據(jù)插入 collection 中, 但是當(dāng)我們刷新頁面的時(shí)候,數(shù)據(jù)會(huì)重置會(huì)原來的數(shù)據(jù),
如果我們要將數(shù)據(jù)全部存下來(即使刷新也會(huì)存在的話), 就需要保存:// var db = new loki('Example'); 這是 db 的由來
db.saveDatabase(error => {
console.log('保存數(shù)據(jù)')
error && console.log(error)
})
獲取數(shù)據(jù):
獲取數(shù)據(jù)是比較靈活的,我這里說兩種方法:
方法一:const dv = coll.addDynamicView('test');
const results = dv.data();
console.log(results)
// 這是results打印結(jié)果
// 0: {name: "odin", email: "odin.soap@lokijs.org", age: 38, meta: {…}, $loki: 1}
// 1: {name: "thor", email: "thor.soap@lokijs.org", age: 25, meta: {…}, $loki: 2}
// 2: {name: "stan", email: "stan.soap@lokijs.org", age: 29, meta: {…}, $loki: 3}
// 3: {name: "oliver", email: "oliver.soap@lokijs.org", age: 31, meta: {…}, $loki: 4}
// 4: {name: "hector", email: "hector.soap@lokijs.org", age: 15, meta: {…}, $loki: 5}
// 5: {name: "achilles", email: "achilles.soap@lokijs.org", age: 31, meta: {…}, $loki: 6}
方法二:const resultsLine = coll.chain().data();
console.log(resultsLine)
// 結(jié)果與方法一相同
獲取數(shù)據(jù)時(shí)篩選想要的數(shù)據(jù):
方法 1 的篩選:
find// 通過 coll 直接獲取
const results4 = coll.find({'age': {'$aeq': 15}});
console.log('獲取數(shù)據(jù) 4',results4)
// 可使用不同的指令:
// 指令名 作用
// $eq ===
// $ne !==
// $aeq ==
// $dteq 時(shí)間上的相等
// $gt >
// $gte >=
// $lt <
// $lte <=
// $between 介于 2 個(gè)數(shù)之間
// 如果不希望使用二進(jìn)制索引,并且希望簡單的javascript比較是可以接受的,我們提供以下操作,由于它們的簡化比較,它們可以提供更好的執(zhí)行速度。
// $gt -> $jgt
// $gte -> $jgte
// $lt -> $jlt
// $lte -> $jlte
// $between -> $jbetween
// $regex 使用正則
applyFindconst dv = coll.addDynamicView('test');
dv.applyFind({ 'name' : 'odin' });
const results = dv.data();
applyWheredv2.applyWhere(function(obj) { return obj.name === 'oliver'; });
// 作用與上述方法相同
applySimpleSort// 根據(jù)年齡進(jìn)行排序
const dv3 = coll.addDynamicView('test3');
dv3.applySimpleSort("age");
const results3 = dv3.data();
console.log(results3)
findOneconst results5 = coll.findOne({'age': {'$aeq': 31}});
// 獲取到的是對象 而不是一個(gè)數(shù)組
console.log('獲取數(shù)據(jù) 5',results5)
findObjectconst results6 = coll.findObject({'age': 38});
// 使用的結(jié)果和 findOne 類似
console.log('獲取數(shù)據(jù) 6',results6)
findObjectsconst results7 = coll.findObjects({'age': 31});
// 返回的是一個(gè)數(shù)組
console.log('獲取數(shù)據(jù) 7',results7)
比較推薦的是使用 addDynamicView 的方式來篩選,而不是通過 collection 直接獲取
需要注意的是 DynamicView 是一個(gè)數(shù)據(jù)格式,他可以 add 可以 get 也可以 remove
方法 2 的篩選:// 簡單的篩選
const resultsLine2 = coll.chain().find({ 'name' : 'odin' }).data();
// 排序:
const resultsLine3 = coll.chain().simplesort('age').data();
當(dāng)然 chain 里還有其他操作,如: limit, map, findAnd, eqJoin, count等等,
我是更推薦使用第一種方法,這里的幾種使用方案我就不詳細(xì)舉例了
還有不建議使用 chain 的 update,remove 等操作,因?yàn)楸O(jiān)聽器里面會(huì)監(jiān)聽不到事件,
這個(gè)問題不知道是故意這么做 還是 bug
修改數(shù)據(jù):
update
與 insert 同理:// 要修改 就需要先獲取要修改的東西是什么
const item = coll.findOne({'age': {'$aeq': 31}});
item.age = 18
coll.update(item);
console.log(coll.chain().data())
// 打印發(fā)現(xiàn)名字為 odin 的年齡已經(jīng)改成了 18
// 當(dāng)然想要持久化就得保存數(shù)據(jù)庫:
db.saveDatabase(error => {
console.log('保存數(shù)據(jù)')
error && console.log(error)
})
findAndUpdatecoll.findAndUpdate({'age': {'$aeq': 25}}, data => {
// 原名"thor"
data.name = 'grewer'
return data
})
// 獲取并且修改 集中在同一個(gè)方法里面
console.log('修改結(jié)果 2', coll.chain().data())
updateWherecoll.updateWhere(data => {
return data.name === 'grewer';
}, data => {
data.age = '999'
return data
})
// 與上面的類似,但是更加自由,而且還可以是用 `{'age': {'$aeq': 15}}` 這種方法來獲取
刪除數(shù)據(jù):
remove
刪除數(shù)據(jù)也是非常簡單的(與更新類似):const item2 = coll.findOne({'age': {'$aeq': 31}});
coll.remove(item2);
console.log(coll.chain().data())
findAndRemovecoll.findAndRemove({'age': {'$aeq': 15}})
// 同 findAndUpdate, 集中了 find 和 remove
console.log('修改結(jié)果 2', coll.chain().data())
removeWhere// 同 updateWhere
coll.removeWhere((value,index)=>{
return index === 1
})
console.log('刪除結(jié)果 3', coll.chain().data())
添加操作的監(jiān)聽:
Loki 的 DB 支持自定義事件,使用如下:// 添加自定義 grewer 事件
db.addListener('grewer',(data) => {
console.log('grewer事件', data)
})
// 觸發(fā)事件
db.emit('grewer','qwerty')
Loki 支持對 collection 添加操作的監(jiān)聽, 監(jiān)聽的事件支持以下事件close
delete
error
flushbuffer
insert
pre-insert
pre-update
update
warning
使用:coll.on('update', (event) => {
console.log('coll change 事件', event)
})
// inset, delete 等其他事件同理
在我們使用 update/findAndUpdate/updateWhere 的時(shí)候就會(huì)自動(dòng)觸發(fā)此回調(diào)了
關(guān)于 Collection transforms
他的官方介紹是這樣的:轉(zhuǎn)換背后的基本思想是允許將結(jié)果集“鏈”過程轉(zhuǎn)換為該過程的對象定義。然后可以選擇命名該數(shù)據(jù)定義,并將其與集合一起保存在數(shù)據(jù)庫中。
一個(gè)簡單的使用:var tx = [
{
type: 'find',
value: {
'name': 'oliver'
}
}
];
console.log(coll.chain(tx).data())
// 打印結(jié)果:
[{
$loki: 4
age: 18
email: "oliver.soap@lokijs.org"
meta: {...}
name: "oliver"
}]
關(guān)于他的使用,感覺像是其他數(shù)據(jù)庫里面的schema, 我這里也沒碰到過具體的情況,所以了解不夠深刻
其他數(shù)據(jù)庫功能:
連表查詢:public eqJoin(
joinData: Collection | Resultset | any[],
leftJoinProp: string | ((obj: any) => string),
rightJoinProp: string | ((obj: any) => string),
mapFun?: (left: any, right: any) => any,
dataOptions?: Partial
): Resultset;
一個(gè)簡單的使用例子:// 創(chuàng)建另一個(gè) collection(表)
var collection = db.addCollection("test", {
unique: ["name"]
});
collection.insert({owner: 0, name: 'Betsy'});
collection.insert({owner: 1, name: 'Bingo'});
collection.insert({owner: 2, name: 'Fifi'});
collection.insert({owner: 3, name: 'Fuzzy'});
collection.insert({owner: 4, name: 'Gizmo'});
// 這是另一個(gè)表
// 進(jìn)行查詢:
const resultSet = coll.eqJoin(collection.chain(), 'id', 'owner')
// 當(dāng) id 和 owner 相等時(shí) 數(shù)據(jù)會(huì)被連接
console.log('連表', resultSet.data())
// 打印一下 console
[{
$loki: 1
left: {name: "odin", id: 0, email: "odin.soap@lokijs.org", age: 38, meta: {…}, …}
meta: {revision: 0, created: 1597421406034, version: 0}
right: {owner: 0, name: "Betsy", meta: {…}, $loki: 1}
},
{
$loki: 2
left: {name: "grewer", id: 1, email: "thor.soap@lokijs.org", age: "999", meta: {…}, …}
meta: {revision: 0, created: 1597421406034, version: 0}
right: {owner: 1, name: "Bingo", meta: {…}, $loki: 2}
},
{
$loki: 3
left: {name: "stan", email: "stan.soap@lokijs.org", age: 29, meta: {…}, $loki: 3}
meta: {revision: 0, created: 1597421406034, version: 0}
right: {}
},
{
$loki: 4
left: {name: "oliver", email: "oliver.soap@lokijs.org", age: 18, meta: {…}, $loki: 4}
meta: {revision: 0, created: 1597421406034, version: 0}
right: {}
},
{
$loki: 5
left: {name: "hector", email: "hector.soap@lokijs.org", age: 15, meta: {…}, $loki: 5}
meta: {revision: 0, created: 1597421406034, version: 0}
right: {}
},
{
$loki: 6
left: {name: "achilles", email: "achilles.soap@lokijs.org", age: 31}
meta: {revision: 0, created: 1597421406034, version: 0}
right: {}
}]
這就是最簡單的連表使用
還有一些沒說到的,但是也就是邊邊角角的東西了,基本就是這些方法的使用
寫在最后
Loki 擁有 adapter 使得他的適用性特別高,但是相對詳細(xì)的使用卻比較少,所以我寫了這篇相對詳細(xì)一點(diǎn)的文章來記錄此數(shù)據(jù)庫的相關(guān)操作
關(guān)于官方文檔地址:
還有這篇文章里面的所有例子的地址:
總結(jié)
以上是生活随笔為你收集整理的lokijs可以用mysql_loki 数据库详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全瓷牙技术要求高吗
- 下一篇: mysql workbench 监控_m