下载 OpenAPI 文档
欢迎查看
本文档免费,请随意查看 Lnx 相关 API 文档。
第一次接触可以向下滚动从 安装
区域开始。
安装
安装 Lnx 非常简单,两种可选方式:Docker 或源码编译。
源码编译
可以使用Rust 最新版本,本项目是基于 rustc 1.52.1
,高于此版本号的都可以。
- 拉取源码
git clone https://github.com/lnx-search/lnx.git
,并进入源码目录 - 运行
cargo build --release
- 从
target/release
目录获取打包输出的二进制文件
只运行项目不输出二进制文件可以直接运行
cargo run --release -- <flags>
使用 Docker
Docker 镜像使用的是 master
分支,此处使用 docker 镜像的 latest
标签
Docker cli 运行
docker run chillfish8/lnx:latest -p "8000:8000" -e "AUTHORIZATION_KEY=hello" -e "LOG_LEVEL=info"
注意:上面的命令未指定数据存储磁盘,重启服务数据会丢失,如果是正式部署强烈建议挂载一个磁盘
使用 docker-compose 运行
version: '3'
services:
lnx:
image: chillfish8/lnx:latest
ports:
- "8000:8000"
volumes:
- "/my/dir:/etc/lnx"
environment:
- AUTHORIZATION_KEY=hello
- LOG_LEVEL=info
运行
运行如下命令可以使用默认参数启动 lnx
运行
lnx <flags>
按默认参数启动服务
注意:通常建议在生产环境使用自定义参数运行 lnx,更多性能优化相关可以查看 lnx 优先说明
帮助
lnx --help
会显示所有命令行参数的详细说明
可选配置参数
Lnx提供了非常多的参数用于自定义配置服务
Authentication Key
如果指定了这个参数每个请求都需要带上授权Key
建议在生产环境必须配置
如下:
-a, --authentication-key <authentication-key>
也可以是环境变量参数:
AUTHENTICATION_KEY=<key>
服务器地址
host地址通常绑定到(127.0.0.1 或 0.0.0.0)
默认是: 127.0.0.1
参数:
-h, --host <host>
环境变量:
HOST=<host>
服务端口
指定服务的端口
默认 8000
参数:
-p, --port <port>
环境变量
PORT=<port>
Log 文件
可选配置日志文件存储
指定一个文件路径
CLI:
--log-file <log-file>
ENV:
LOG_FILE=<log-file>
日志等级
日志等级过滤,高于此当前等级的日志将不会显示
默认:info
CLI:
--log-level <log-level>
ENV:
LOG_LEVEL=<log-level>
美化日志
可选布尔值对不同等级日志使用 ASNI 颜色。如果是使用文件记录日志会关闭此功能。
默认:true
CLI:
--pretty-logs <pretty-logs>
ENV:
PRETTY_LOGS=<pretty-logs>
静默搜索
可选布尔值,关闭每个搜索请求的信息和等级日志,可以有效提高性能。
默认:false
CLI:
--silent-search <silent-search>
ENV:
SILENT_SEARCH=<silent-search>
运行时线程
指定 tokio
运行时的可用线程数
如果不指定,默认使用当前机器的逻辑核心数量
CLI:
-t, --runtime-threads <runtime-threads>
ENV:
RUNTIME_THREADS=<runtime-threads>
管理索引
创建和管理索引非常简单,一旦lnx 配置成功就不需要持续重新定义它。
踩坑
创建索引前理解系统行为很重要,有很多坑即使你的头撞破南墙也想不明白,如为什么没有更新或被莫名奇秒删除。
- 本系统只有新增和删除,想更新索引必须先删除再重新创建,所有数据在操作中都会丢失。原因是索引是模式完整的并且定义时字段必须存在(后期可能会修复)
- 创建索引是非常繁重的操作,不仅要在所有索引上获取全局锁,从而停止其它任何正在进行的操作,而且还要生成和创建多个线程和线程池(稍后将详细介绍)。它们不能在使用过程中被随机制造,也不能通过用户输入来制造,否则会导致严重的问题
- 删除索引会清除所有保存的数据,意味着任何之前上传的文档都会被清除
max_concurrency
决定读取并发数,reader_threads
控制每个读取可使用的线程数,所以你最少生成的线程数为:max_concurrency * reader_threads + writer_thread + 1
(用于写线程)
支持的字段类型
string
类似text
,不会被索引(支持布尔型stored
)text
类似string
,但会被索引(支持布尔型stored
)f64
64位浮点值(支持IntOptions
)i64
64位整形值(支持IntOptions
)u64
64位无符号整形值(支持IntOptions
)date
UTC日期值,以u64无符号整形的形式存储(支持IntOptions
)
Int Options
斜体的字段表示可选
索引(indexed)
:bool - 是否索引此字段。将一个整数设置为索引,将会为这个整数的每个值生成一个发布列表。_快速(fast)_
: 单值或多值(‘single’ or ‘multi’) - 将字段设置为具有给定基数的快速字段,从而使其成为单值或多值字段。快速字段是为随机访问设计的。访问时间类似于数组中的随机查找。如果快速字段关联多个值,则只保留最后一个。存储sotred
: bool - 设置字段为存储型。只有开启了存储型的字段才会持久化存储。
创建索引
- 请求体类型: application/json
- override_if_exists: boolean(如果存在是否覆写) 默认:
false
- index(required): object(IndexDeclaration)
Responses
1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
- status(required): 整形(状态)
-
2. 400 索引已存在(且 override 未设置)或 请求参数有误
响应体类型: application/json
status(required): 整形(状态)
-
3. 401 无权限操作
响应体类型: application/json
status(required): 整形(状态)
-
4. 422 服务器无法解析请求参数
响应体类型: application/json
status(required): 整形(状态)
- data(required): 字符串或对象(数据)
请求示例
```json // post /indexes // Payload: // content-type: application/json { “override_if_exists”: false, “index” {
} }"name": "string",
"storage_type": "memory",
"fields": {
"property1": {
"type": "f64",
"stored": true,
"indexed": true,
"fast": "single"
},
"property2": {
"type": "f64",
"stored": true,
"indexed": true,
"fast": "single"
},
},
"search_fields": ["string"],
"boost_fields: {},
"reader_threads": 1,
"max_concurrency": 2,
"writer_buffer": 300000,
"writer_threads": 0,
"set_conjunction_by_default": false,
"use_fast_fuzzy": false,
"strip_stop_words": false,
"auto_commit": 0,
// Response // content-type: application/json { “status”: 0, “data”: “string” }
<a name="d4icx"></a>
### Delete Index
- index(required): string(Index)
<a name="cCMJu"></a>
#### Responses
<a name="ydqbQ"></a>
##### 1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="BVrTt"></a>
##### 2. 400 索引不存在
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="YFGwg"></a>
##### 3. 401 无权限操作
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="XRfiV"></a>
##### 4. 422 不会有这个错误(文档类问题)
<a name="QCZfe"></a>
#### 请求示例
```json
// DELETE /indexes/{index}
// Response:
// content-type: application/json
{
"status": 0,
"data": "string",
}
管理事务
事务是Lnx中最重要的操作之一,它控制读取器可以查看哪些数据以及哪些数据是完全处理和保存的。
Lnx的事务和传统数据库的事务有一些主要的区别:
- 对特定的索引每次应该只有一个系统与写入器交互。系统的所有写操作是在一个单一的队列中,因此如果一个系统添加文档,另一个系统提交,那么文档将会被确认并保存到磁盘。
- 强烈建议为写入端点添加锁*
- 事务是隐式和显式的,这意味着你不需要声明一个事务,只需要简单的分别调用提交和回滚,会对上次提交后做的所有写操作产生影响,一旦完成提交就不能再进行回滚。
提交 commit
结束自上次提交以来对索引文档的任何更改并保存它们。
- index(required): string(Index)
Responses
1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
- status(required): 整形(状态)
-
2. 400 索引不存在
响应体类型: application/json
status(required): 整形(状态)
-
3. 401 无权限操作
响应体类型: application/json
status(required): 整形(状态)
- data(required): 字符串或对象(数据)
4. 422 不会有这个错误(文档类问题)
请求示例
// POST /indexes/{index}/commit
// Response
// content-type: application/json
{
"status": 0,
"data": "string"
}
回滚 Rollback
恢复自上次提交以来对索引文档的所有改动
- index(required): string(Index)
Responses
1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
- status(required): 整形(状态)
-
2. 400 索引不存在
响应体类型: application/json
status(required): 整形(状态)
-
3. 401 无权限操作
响应体类型: application/json
status(required): 整形(状态)
- data(required): 字符串或对象(数据)
4. 422 不会有这个错误(文档类问题)
请求示例
// POST /indexes/{index}/rollback
// Response
// content-type: application/json
{
"status": 0,
"data": "string"
}
管理文档
文档只能被添加或移除,没有更新。明确的使用这种方式是最好的因此没有更新接口。每个文档都会生成对应的64位数字,该数字做为字符串返回,以便以后访问。
添加文档
添加一个文档非常简单,可以使用 JSON 对象添加一个文档也可以提交一个对象数组。
会检查每个文档对应的必须字段,任何文档缺失字段都会拒绝整个请求。
请求URL参数:
- index(required): string(Index)
请求体结构: application/json
- property name*: 字符串数组或字符串
Responses
1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
- status(required): 整形(状态)
-
2. 400 索引不存在
响应体类型: application/json
status(required): 整形(状态)
-
3. 401 无权限操作
响应体类型: application/json
status(required): 整形(状态)
- data(required): 字符串或对象(数据)
4. 422 不能解析请求体
请求示例
```json // POST /indexes/{index}/documents // payload // content-type: application json
[]
// Response // content-type: application/json { “status”: 0, “data”: “string }
<a name="rn79f"></a>
### 删除指定文档
文档只能通过指定条件删除,你需要确保条件是唯一的,否则这个方法会删除多个文档。<br />注意:只有快速字段可以起作用,所以最好是使用唯一的ID或使用文档ID的 `_id` 字段。
请求URL参数:
- index(required): string(Index)
请求体结构: application/json
- property name*: 字符串数组或字符串
<a name="HVctF"></a>
#### Responses
<a name="HGbDI"></a>
##### 1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="jUfJO"></a>
##### 2. 400 索引不存在
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="S2dBw"></a>
##### 3. 401 无权限操作
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="nPuJ5"></a>
##### 4. 422 不能解析请求体
<a name="P2Qd3"></a>
#### 请求示例
```json
// DELETE /indexes/{index}/documents
// payload
// content-type: application json
[]
// Response
// content-type: application/json
{
"status": 0,
"data": "string
}
清除所有文档
使用这个接口可以清除索引的所有文档
请求URL参数:
index(required): string(Index)
Responses
1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
status(required): 整形(状态)
-
2. 400 索引不存在
响应体类型: application/json
status(required): 整形(状态)
-
3. 401 无权限操作
响应体类型: application/json
status(required): 整形(状态)
- data(required): 字符串或对象(数据)
4. 422 不会有这个错误
请求示例
```json // DELETE /indexes/{index}/documents/clear // payload // content-type: application json
[]
// Response // content-type: application/json { “status”: 0, “data”: “string }
<a name="ueY8O"></a>
### 通过ID获取 文档
使用指定的 document_id 从索引获取一个文档
请求URL参数:
- index(required): string(索引)
- document_id(required): integer(文档ID)
<a name="lVIrE"></a>
#### Responses
<a name="pLXlN"></a>
##### 1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="xUMBQ"></a>
##### 2. 400 索引不存在
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="pdscA"></a>
##### 3. 401 无权限操作
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="l0pVp"></a>
##### 4. 422 不会产生此错误
<a name="ko2ch"></a>
#### 请求示例
```json
// GET /indexes/{index}/documents/{document_id}
// payload
// content-type: application json
[]
// Response
// content-type: application/json
{
"status": 0,
"data": "string
}
执行搜索
添加完文档就可以准备开始搜索了!
Lnx为搜索索引提供了4种主要方式:
一般 normal
这不是类型宽容的快速查询解析系统,但对自定义用户查询非常强大,比如日志查询。模糊 fuzzy
模糊查询会忽略标准解析器可能会处理的自定义查询系统,但条件类型是宽容的。- 如果指定的索引设置了
use_fast_fuzzy
为true
,将会使用模糊查询系统。
- 如果指定的索引设置了
more-like-this
不同于前两种方式,这种方式接收一个文档引用地址然后生成一样的文档。这种方式对书籍一类非常有用,需要类似的条件。条件 term
期望查询条件中是明确的值,不会有任何模糊匹配或normal
方式解析。
搜索索引
通过指定条件搜索索引
请求URL参数:
- index(required): string(Index)
请求体结构: application/json
- query(required): 字符串或 QueryData(对象) 或 QueryData 对象数组(Qeury)
- limit: 整形(Limit)[0..0] 默认20
- offset: 整数(Offset) >=0 默认0
- order_by: 字符串(Order by)
- sort: 默认 desc 枚举值: acs/desc
Responses
1. 200 标准Lnx返回,有简单的确认信息
响应体类型: application/json
- status(required): 整形(状态)
-
2. 400 索引不存在
响应体类型: application/json
status(required): 整形(状态)
-
3. 401 无权限操作
响应体类型: application/json
status(required): 整形(状态)
- data(required): 字符串或对象(数据)
4. 422 不能解析请求体
请求示例
```json // POST /indexes/{index}/search // payload // content-type: application/json
{ “query”: “string”, “limit”: 20, “offset”: 0, “order_by”: “string”, “sort”: “acs” }
// Response // content-type: application/json { “status”: 0, “data”: { “hits”: “”, //[…] “count”: 0, “time_taken”: 0 } }
<a name="LHP64"></a>
## Lnx 安全
通常 lnx是在 api 后面或有反向代理,但还是强烈建议为 Lnx 开启 token 令牌认证,的确会有错误会发生。<br />你是幸运的,Lnx为你提供了一个简单的可以自定义的权限认证系统。<br />当你第一次配置权限你需要在启动 lnx 时为cli传递一个参数 `--super-user-key <key>`,这不仅是你创建新的token来访问接口也是控制 lnx 是否启用权限认证。<br />向接口传递认证码需要在请求头使用如下格式:
```json
Authorization: <token>
警告
Lnx还不是全面公开的设计,即使有认证系统会防止用户访问他们不应该获取的内容,但依然强烈建议不要只依赖这套认证系统来保护你的内容。大部分情况下我们建议把 lnx 放在已有API后面。
权限
- MODIFY_ENGINE -
1 << 0 = 1
- 拥有此权限的用户可以创建和删除索引。这是除超级管理员之外最危险的权限。
- SEARCH_INDEX -
1 << 1 = 2
- 拥有此权限的用户可以搜索允许的索引
- MODIFY_DOCUMENTS -
1 << 2 = 4
- 拥有此权限的用户可以从允许的索引添加或删除文档
- MODIFY_STOP_WORDS -
1 << 3 = 8
- 拥有此权限的用户可以从允许的索引里添加或删除停止词
- MODITY_AUTH -
1 << 4 = 16
- 拥有此权限的用户可以创建、修改和废除访问令牌
- SUPER_USER -
1 | 2| 4 | 8 | 16 = 31
- 这是上面所有权限的集合,可以控制所有。
权限计算
权限是按位计算,意味着 lnx 期望的是一个你需要的组合权限的整数。你可以通过取两个权限的按位 OR / |
作为 权限1 + 权限2 的标志来计算出你需要的权限整数值。例如,如果我位希望令牌能够修改文档和搜索索引,可以如下计算:
permissions = 1 << 2 | 1 << 1
创建令牌
按指定的元数据创建新的访问令牌
请求体结构: application/json
- permissions(required): 整数(权限)
- user: 字符串(用户)
- descrioption: 字符串(描述)
- allowed_indexes: 字符串数组(允许的索引)
Responses
1. 200 返回包含令牌和其它元数据的对象
响应体类型: application/json
- status(required): 整形(状态)
-
2. 401 无权限操作
响应体类型: application/json
status(required): 整形(状态)
- data(required): 字符串或对象(数据)
4. 422 不能解析请求体
请求示例
```json // POST /auth // payload // content-type: application/json
{ “permissions”: 0, “user”: “string”, “description”: “string”, “alowed_indexes”: [“string”] }
// Response // content-type: application/json { “status”: 0, “data”: { “permissions”: 0, “user”: “string”, “description”: “string”, “allowed_indexes”: [], “created”: “20210-11-23T14:15:22Z”, “token”: “string” } }
<a name="mu5oH"></a>
### 废除所有令牌
废除所有访问令牌
<a name="Y270z"></a>
#### 警告
此功能只适用于紧急情况。运行此命令会删除所有访问令牌包括超级管理员,造成的后果由你自己承担。
<a name="AIFtJ"></a>
#### Responses
<a name="HzdPK"></a>
##### 1. 200 标准确认信息
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="jUffh"></a>
##### 2. 401 无权限操作
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="GZpcL"></a>
##### 4. 422 不能解析请求体
<a name="mvBA9"></a>
#### 请求示例
```json
// DELETE /auth
// Response
// content-type: application/json
{
"status": 0,
"data": "string"
}
废除令牌
Responses
1. 200 标准确认信息
响应体类型: application/json
- status(required): 整形(状态)
-
2. 400 Url中指定的令牌不存在
响应体类型: application/json
status(required): 整形(状态)
-
3. 401 无权限操作
响应体类型: application/json
status(required): 整形(状态)
- data(required): 字符串或对象(数据)
4. 422 不会发生此错误
请求示例
```json // DELETE /auth/{token}/revoke
// Response // content-type: application/json { “status”: 0, “data”: “string” }
<a name="j6SpS"></a>
### 编辑令牌
编辑指定令牌的权限和元数据,请求体数据会替换所有字段,设置或移除字段
请求体结构: application/json
- permissions(required): 整形数字(权限)
- user: 字符串(用户)
- description: 字符串(描述)
- allowed_indexes: 字符串数组(允许的索引)
<a name="eTGGM"></a>
#### Responses
<a name="Vg36x"></a>
##### 1. 200 返回令牌及其它元数据
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="H6vhM"></a>
##### 2. 400 Url中指定的令牌不存在
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="H9nV4"></a>
##### 3. 401 无权限操作
响应体类型: application/json
- status(required): 整形(状态)
- data(required): 字符串或对象(数据)
<a name="kY0uT"></a>
##### 4. 422 请求体解析失败
<a name="VFbmg"></a>
#### 请求示例
```json
// POST /auth/{token}/edit
// Request
// content-type: application/json
{
"permissions": 0,
"user": "string",
"description": "string",
"allowed_indexes": ["string"]
}
// Response
// content-type: application/json
{
"status": 0,
"data": "string"
}
优化索引
了解你的工作量
并不是每一组数据都有相同的最佳配置,在选择配置时,注意以下几点:
大型数据集(数百万以上数据集)
搜索大型数据集可以设置更多的读取器线程和更少的最大并发量,而更少的读取器线程和更多的并发线程会有负面影响,即一次以非常缓慢的速度运行许多搜索,而不是快速地运行少量搜索。
小型数据集(几千个数据集)
较小的数据集通过不能很好的利用大量的读取线程,这是因为数据没有被分割成足够的段来充分利用并行计算。
通常对于较小的数据集,最好是更高的并发性和更少的读取线程。
例如,示例中的 moviews.json 数据集大致优化为1 或 2个读取器线程和 n*3
个最大并发数,其中 n 中机器上的 CPU 核心数。也可以根据 CPU 的时钟速度进行调整,所以在确认配置之前仍要进行基准测试。