Node.JS客户端使用帮助

OnceDB by onceoa on 1582637888654


OnceDB

OnceDB 动态模式内存数据库,node.js客户端驱动。

安装

npm install oncedb

快速使用

创建 oncedb 客户端实例:

var oncedb = require('oncedb')()

会自动连接到本地 oncedb-server 数据库服务。

options 选项

OnceDB 连接选项

const oncedb = OnceDB(options, cb)

Options 选项:

  • host: 服务器地址
  • port: [Number] 服务器端口号
  • auth: oncedb-server 服务设置的密码
  • select: [Number] 选中的数据库
  • schema: 要装载的 schema 文件夹地址

示例

const OnceDB = require('oncedb')
const options = {
    auth    : '1234567890'
  , select  : 0
  , host    : '127.0.0.1'
  , port    : 6379
}
const oncedb = OnceDB(options);

带回调示例:

const oncedb = OnceDB(options, function(err) {
    if (err {
        console.log('connect error', err)
        return
    }

    console.log('connected')
})

示例

创建了 oncedb.client 之后,就可以更新或查询数据,这是 testOnceDB.js 的示例:

var util    = require('util');
var oncedb  = require('oncedb')();

oncedb.schema('user', {
    username  : 'id'
  , password  : ''
  , title     : 'group'
  , skills    : 'keywords'
  , birthday  : 'date;sort'
})

oncedb.upsert('user', { username: 'dota', password: '123456', title: 'SDEII', skills: 'c,go,node.js', birthday: '2000-01-01' }, function(err) {
  if (err) {
    console.log(err)
  }
})

oncedb.upsert('user', { username: 'like', password: '654321', title: 'SDEI', skills: 'javascript,node.js', birthday: '2010-12-12' }, function(err) {
  if (err) {
    console.log(err)
  }

  //When the update is complete, start the query
  oncedb.select('user', { skills: 'node.js' }, function(err, rows) {
    if (err) {
      console.log(err)
    }

    console.log(rows)
  })
})

运行 testOnceDB.js:


$ node testOnceDB.js
[
  {
    _key: 'user:dota',
    skills: [ 'c', 'go', 'node.js' ],
    username: 'dota',
    password: '123456',
    title: 'SDEII',
    birthday: '2000-01-01'
  },
  {
    _key: 'user:like',
    skills: [ 'javascript', 'node.js' ],
    username: 'like',
    password: '654321',
    title: 'SDEI',
    birthday: '2010-12-12'
  }
]

确保Oncedb-server服务正在运行。

Promises & async/await 语法

您可以包装 oncedb 的方法以支持 async / await 语法。 使用util.promisify方法:

const util    = require('util');
const oncedb  = require('oncedb')();

// promisify methods
const insert  = util.promisify(oncedb.insert).bind(oncedb)
const update  = util.promisify(oncedb.update).bind(oncedb)
const upsert  = util.promisify(oncedb.upsert).bind(oncedb)
const select  = util.promisify(oncedb.select).bind(oncedb)
const remove  = util.promisify(oncedb.remove).bind(oncedb)

;(async() => {

  oncedb.schema('user', {
      username  : 'id'
    , password  : ''
    , title     : 'group'
    , skills    : 'keywords'
    , birthday  : 'date;sort'
  })

  await upsert('user', { username: 'dota', password: '123456', title: 'SDEII', skills: 'c,go,node.js', birthday: '2000-01-01' })
  await upsert('user', { username: 'like', password: '654321', title: 'SDEI', skills: 'javascript,node.js', birthday: '2010-12-12' })

  let rows = await select('user', { skills: 'c' })
  console.log(rows)

})()

运行 testOnceDB.js

$ node testOnceDB.js
rows.count 2
rows.length 1
[ { _key: 'user:dota',
    skills: [ 'c', 'go', 'node.js' ],
    username: 'dota',
    password: '1234',
    title: 'SDEII',
    birthday: '2000-01-01' } ]

文档

参考: OnceDB 数据修改和查询帮助文档

oncedb.client

oncedb.client 是基于 node-redis 的对象,并添加了OnceDB自定义扩展命令。.

您可以在这些命令上使用 util.promisify 方法,以支持 async/ await 语法。

const util    = require('util');
const oncedb  = require('oncedb')();

const hgetall = util.promisify(oncedb.client.hgetall).bind(oncedb.client)
const zrange  = util.promisify(oncedb.client.zrange).bind(oncedb.client)

oncedb.upsert 更新数据

更新数据,如果不存在则添加。

oncedb.upsert(schemaName, updateObject, callback)
  • oncedb.insert: 插入不存在的数据
  • oncedb.update: 更新现有数据
  • oncedb.remove: 删除数据

oncedb.select 查询数据

oncedb.select 等效于 oncedb.find,

oncedb.select(schemaName, [ where, ] callback [, options ])
oncedb.select(schemaName, where, [ options, ] callback)

where 条件:

  • 相等查询: { id: 'value' }
  • 包含查询: { id: { '~': 'partial string' } }
  • 比较查询: { id: { '>': 10 } }

options 选项:

  • from: 从0开始的行数
  • to: 要结束的行数,最后一个 -1 或 (rows.count -1)
  • range: 数组对象,等效于 [ from, to ]
  • desc 倒序
  • order / sort / between: sort / order 排序字段,你可以指定字段的分数权重范围 [ field, startScore, stopScore ]
  • index: true 或 string. 将搜索结果输出到索引,在索引搜索可用

rows.count 数据总数

如果使用全文搜索: rows.count = -1 如果使用索引搜索: rows.count >= 0

;(async() => {
  oncedb.schema('blog', { id: 'id;sequence', visit: 'sort' })

  await upsert('blog', { visit: 10 })
  await upsert('blog', { visit: 22 })
  await upsert('blog', { visit: 44 })
  await upsert('blog', { visit: 14 })

  let blogs = await select('blog', {}, { order: [ 'visit', 10, 30 ], range: [0, 1], desc: true })
  console.log('rows.count', blogs.count)
  console.log(blogs)
})()

输出:

rows.count 3
[
  { _key: 'blog:2', id: '2', visit: '22' },
  { _key: 'blog:4', id: '4', visit: '14' }
]

oncedb.remove 删除数据

删除查询的数据

oncedb.remove(schemaName, where [,callback])

schema 模式

OnceDB中 的 Schema 类似于SQL数据库中的表。 Schema 可以指定字段类型,辅助索引类型等。

oncedb.schema(schemaName, definitions [,callback])

字段类型

字段由关键字定义。

schema: id 主键

每个模式必须只有一个ID字段。

可选参数

  • 自定义索引名称
  • 自定义分数权重
;(async() => {
  oncedb.schema('user', {
      username  : 'id("users", this.ctime)'
    , ctime     : ''
  })

  await upsert('user', { username: 'dota', ctime: 123456 })
  let lines = await zrange('users', 0, -1, 'withscores')
  console.log(lines)
})()

结果:

[ 'dota', '123456' ]

schema: sequence 自增数字

可选参数

  • prefix: 序列的前缀
  • start: 开始编号
  • increment: 增量数

带参数示例

;(async() => {
  oncedb.schema('blog', { id: 'id;sequence("B", 1000, 10)', title: '' })

  await upsert('blog', { title: 'blog 1' })
  await upsert('blog', { title: 'blog 2' })
  let blogs = await select('blog')
  console.log(blogs)
})()

结果

[
  { _key: 'blog:B1010', id: 'B1010', title: 'blog 1' },
  { _key: 'blog:B1020', id: 'B1020', title: 'blog 2' }
]

schema: date/ datetime 日期

日期在数据库中存的是数字。

;(async() => {
  oncedb.schema('user', { username: 'id', ctime: 'date' })

  await upsert('user', { username: 'dota', ctime: '2000-10-10' })
  await upsert('user', { username: 'hero', ctime: '2020-10-10' })

  let user  = await hgetall('user:dota')
  let users = await select('user', { ctime: { '>': '2010-1-1' } })
  console.log(user)
  console.log(users)
})()

结果:

{ username: 'dota', ctime: '971136000000' }
[ { _key: 'user:hero', ctime: '2020-10-10', username: 'hero' } ]

可以使用 dateFormat 和 dateTimeformat 指定日期输出格式

oncedb.dateFormat     = 'yyyy/mm/dd'
oncedb.datetimeFormat = 'yyyy/mm/dd hh:MM:ss'
  
let users = await select('user', {}, { from: 0, to: 0 })
console.log(users)

结果:

[ { _key: 'user:dota', username: 'dota', ctime: '2000/10/10' } ]

schema: group, index 分组索引

分组索引使用 'group' 或 'index'

;(async() => {
  oncedb.schema('blog', { id: 'id;sequence', poster: 'group' })

  await upsert('blog', { poster: 'dota' })
  await upsert('blog', { poster: 'hero' })
  await upsert('blog', { poster: 'dota' })

  let blogs = await select('blog', { poster: 'dota' })
  console.log(blogs)
})()

结果:

[
  { _key: 'blog:1', poster: 'dota', id: '1' },
  { _key: 'blog:3', poster: 'dota', id: '3' }
]

默认分组索引名称格式: *schema.field:value

  let lines = await zrange('*blog.poster:dota', 0, -1)
  console.log(lines)
  > [ '1', '3' ]

可选参数

  • 自定义索引名称
  • 自定义分数权重
oncedb.schema('blog', { id: 'id;sequence', poster: 'group("blog_user", Date.now())' })

schema: keywords, groups 关键字索引

关键字索引:使用 “keywords” 或 “groups” 用逗号或数组对象分隔关键字:

;(async() => {
  oncedb.schema('blog', { id: 'id;sequence', keys: 'keywords' })

  await upsert('blog', { keys: 'node.js,c,go' })
  await upsert('blog', { keys: [ 'go', 'c' ] })
  await upsert('blog', { keys: 'node.js,c' })
  // select data which has go and c
  let blogs = await select('blog', { keys: ['go', 'c'] })
  console.log(blogs)
})()

结果:

[
  { _key: 'blog:1', keys: [ 'node.js', 'c', 'go' ], id: '1' },
  { _key: 'blog:2', keys: [ 'go', 'c' ], id: '2' }
]

可选参数

  • 自定义索引名称
  • 自定义分数权重
oncedb.schema('blog', { id: 'id', keys: 'keywords("blog_keys", Date.now())' })

schema: sort, order 排序索引

排序索引使用 "sort" 或 "order"

;(async() => {
  oncedb.schema('blog', { id: 'id;sequence', visit: 'sort' })

  await upsert('blog', { visit: 10 })
  await upsert('blog', { visit: 22 })
  await upsert('blog', { visit: 44 })
  await upsert('blog', { visit: 14 })

  let blogs = await select('blog', {}, { order: [ 'visit', 10, 20 ] })
  console.log(blogs)
})()

结果:

[
  { _key: 'blog:1', id: '1', visit: '10' },
  { _key: 'blog:4', id: '4', visit: '14' }
]

可选参数

  • 自定义索引名称

其它关键字

schema: required
schema: int
schema: number
schema: array, json, object
schema: min (minNumber)
schema: max (maxNumber)
schema: minlen (minLength)
schema: maxlen (maxLength)

oncedb.extend 扩展

扩展现有 schema.

连接查询

可以用数组实现连接查询

oncedb.select(schemaName, [query1, query2 ...], options, cb)
oncedb.select(schemaName, [[query1, options1], [query2, options2] ...], options, cb)

示例

oncedb.schema('issue', { id:'id;sequence', group:'index', keys:'keywords', priority:'sort' })

await upsert('issue', { group: 'bug', keys: 'node.js,c,go', priority: 1 })
await upsert('issue', { group: 'task', keys: 'java,c,go', priority: 7 })
await upsert('issue', { group: 'task', keys: 'java,c', priority: 4 })

合并查询两个条件:返回3行数据

var issues = await select('issue', [ { group: 'task'}, { priority: 1 } ])

合并带有参数的查询:返回2行数据

var issues = await select('issue', [
    [ { group: 'task'}, { between: [ 'priority', 7, 10 ] } ]
  , { keys: 'node.js' }
])

事件

ready

oncedb.on('ready', function() {
  console.log('ready')
})

error

oncedb.on('error', function(err) {
  console.log('error', err)
})

connect

oncedb.on('connect', function(err) {
  console.log('connect')
})

oncedb.client 扩展指令

参考: OnceDB 指令参考

oncedb.client.execute(command, cb)
oncedb.client.hsearch(keyPattern, conditions, cb)
oncedb.client.horsearch(keyPattern, conditions, cb)
oncedb.client.hsearchids(keyPattern, keys, conditions, cb)
oncedb.client.hselect(fields, keys, cb)
oncedb.client.hmgetall(args, cb)
oncedb.client.hmget(args, cb)
oncedb.client.hmset(args, cb)
oncedb.client.zhsearch(zsetKey, from, to, schemaName, conditions, cb)
oncedb.client.zrangehmget(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrevrangehmget(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrangehmgetbyscore(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrevrangehmgetbyscore(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrangehmgetbyscore(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrevrangehmsumbyscore(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrangehmsum(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrevrangehmsum(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrangehmsumbyscore(zsetKey, from, to, schemaAndField, cb)
oncedb.client.zrevrangehmsumbyscore(zsetKey, from, to, schemaAndField, cb)
oncedb.client.shmget(setKey, schemaAndField, cb)
oncedb.client.shmset(setKey, schemaName, updateObject, cb)
oncedb.client.shmsum(setKey, schemaAndField, cb)

Previous article: 搜索、查询、计算、求和指令