https://lnx.rs

下载 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 运行

  1. docker run chillfish8/lnx:latest -p "8000:8000" -e "AUTHORIZATION_KEY=hello" -e "LOG_LEVEL=info"

注意:上面的命令未指定数据存储磁盘,重启服务数据会丢失,如果是正式部署强烈建议挂载一个磁盘

使用 docker-compose 运行

  1. version: '3'
  2. services:
  3. lnx:
  4. image: chillfish8/lnx:latest
  5. ports:
  6. - "8000:8000"
  7. volumes:
  8. - "/my/dir:/etc/lnx"
  9. environment:
  10. - AUTHORIZATION_KEY=hello
  11. - LOG_LEVEL=info

运行

运行如下命令可以使用默认参数启动 lnx

运行

  1. lnx <flags>

按默认参数启动服务

注意:通常建议在生产环境使用自定义参数运行 lnx,更多性能优化相关可以查看 lnx 优先说明

帮助

  1. lnx --help

会显示所有命令行参数的详细说明

可选配置参数

Lnx提供了非常多的参数用于自定义配置服务

Authentication Key

如果指定了这个参数每个请求都需要带上授权Key
建议在生产环境必须配置
如下:

  1. -a, --authentication-key <authentication-key>

也可以是环境变量参数:

  1. AUTHENTICATION_KEY=<key>

服务器地址

host地址通常绑定到(127.0.0.1 或 0.0.0.0)
默认是: 127.0.0.1
参数:

  1. -h, --host <host>

环境变量:

  1. HOST=<host>

服务端口

指定服务的端口
默认 8000
参数:

  1. -p, --port <port>

环境变量

  1. PORT=<port>

Log 文件

可选配置日志文件存储
指定一个文件路径
CLI:

  1. --log-file <log-file>

ENV:

  1. LOG_FILE=<log-file>

日志等级

日志等级过滤,高于此当前等级的日志将不会显示
默认:info
CLI:

  1. --log-level <log-level>

ENV:

  1. LOG_LEVEL=<log-level>

美化日志

可选布尔值对不同等级日志使用 ASNI 颜色。如果是使用文件记录日志会关闭此功能。
默认:true
CLI:

  1. --pretty-logs <pretty-logs>

ENV:

  1. PRETTY_LOGS=<pretty-logs>

静默搜索

可选布尔值,关闭每个搜索请求的信息和等级日志,可以有效提高性能。
默认:false
CLI:

  1. --silent-search <silent-search>

ENV:

  1. SILENT_SEARCH=<silent-search>

运行时线程

指定 tokio运行时的可用线程数
如果不指定,默认使用当前机器的逻辑核心数量
CLI:

  1. -t, --runtime-threads <runtime-threads>

ENV:

  1. 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): 整形(状态)
  • data(required): 字符串或对象(数据)

    2. 400 索引已存在(且 override 未设置)或 请求参数有误

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(required): 字符串或对象(数据)

    3. 401 无权限操作

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(required): 字符串或对象(数据)

    4. 422 服务器无法解析请求参数

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(required): 字符串或对象(数据)

    请求示例

    ```json // post /indexes // Payload: // content-type: application/json { “override_if_exists”: false, “index” {
    1. "name": "string",
    2. "storage_type": "memory",
    3. "fields": {
    4. "property1": {
    5. "type": "f64",
    6. "stored": true,
    7. "indexed": true,
    8. "fast": "single"
    9. },
    10. "property2": {
    11. "type": "f64",
    12. "stored": true,
    13. "indexed": true,
    14. "fast": "single"
    15. },
    16. },
    17. "search_fields": ["string"],
    18. "boost_fields: {},
    19. "reader_threads": 1,
    20. "max_concurrency": 2,
    21. "writer_buffer": 300000,
    22. "writer_threads": 0,
    23. "set_conjunction_by_default": false,
    24. "use_fast_fuzzy": false,
    25. "strip_stop_words": false,
    26. "auto_commit": 0,
    } }

// Response // content-type: application/json { “status”: 0, “data”: “string” }

  1. <a name="d4icx"></a>
  2. ### Delete Index
  3. - index(required): string(Index)
  4. <a name="cCMJu"></a>
  5. #### Responses
  6. <a name="ydqbQ"></a>
  7. ##### 1. 200 标准Lnx返回,有简单的确认信息
  8. 响应体类型: application/json
  9. - status(required): 整形(状态)
  10. - data(required): 字符串或对象(数据)
  11. <a name="BVrTt"></a>
  12. ##### 2. 400 索引不存在
  13. 响应体类型: application/json
  14. - status(required): 整形(状态)
  15. - data(required): 字符串或对象(数据)
  16. <a name="YFGwg"></a>
  17. ##### 3. 401 无权限操作
  18. 响应体类型: application/json
  19. - status(required): 整形(状态)
  20. - data(required): 字符串或对象(数据)
  21. <a name="XRfiV"></a>
  22. ##### 4. 422 不会有这个错误(文档类问题)
  23. <a name="QCZfe"></a>
  24. #### 请求示例
  25. ```json
  26. // DELETE /indexes/{index}
  27. // Response:
  28. // content-type: application/json
  29. {
  30. "status": 0,
  31. "data": "string",
  32. }

管理事务

事务是Lnx中最重要的操作之一,它控制读取器可以查看哪些数据以及哪些数据是完全处理和保存的。

Lnx的事务和传统数据库的事务有一些主要的区别:

  • 对特定的索引每次应该只有一个系统与写入器交互。系统的所有写操作是在一个单一的队列中,因此如果一个系统添加文档,另一个系统提交,那么文档将会被确认并保存到磁盘。
  • 强烈建议为写入端点添加锁*
  • 事务是隐式和显式的,这意味着你不需要声明一个事务,只需要简单的分别调用提交和回滚,会对上次提交后做的所有写操作产生影响,一旦完成提交就不能再进行回滚。

提交 commit

结束自上次提交以来对索引文档的任何更改并保存它们。

  • index(required): string(Index)

Responses

1. 200 标准Lnx返回,有简单的确认信息

响应体类型: application/json

  • status(required): 整形(状态)
  • data(required): 字符串或对象(数据)

    2. 400 索引不存在

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(required): 字符串或对象(数据)

    3. 401 无权限操作

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(required): 字符串或对象(数据)
    4. 422 不会有这个错误(文档类问题)

    请求示例

  1. // POST /indexes/{index}/commit
  2. // Response
  3. // content-type: application/json
  4. {
  5. "status": 0,
  6. "data": "string"
  7. }

回滚 Rollback

恢复自上次提交以来对索引文档的所有改动

  • index(required): string(Index)

Responses

1. 200 标准Lnx返回,有简单的确认信息

响应体类型: application/json

  • status(required): 整形(状态)
  • data(required): 字符串或对象(数据)

    2. 400 索引不存在

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(required): 字符串或对象(数据)

    3. 401 无权限操作

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(required): 字符串或对象(数据)
    4. 422 不会有这个错误(文档类问题)

    请求示例

    1. // POST /indexes/{index}/rollback
    2. // Response
    3. // content-type: application/json
    4. {
    5. "status": 0,
    6. "data": "string"
    7. }

管理文档

文档只能被添加或移除,没有更新。明确的使用这种方式是最好的因此没有更新接口。每个文档都会生成对应的64位数字,该数字做为字符串返回,以便以后访问。

添加文档

添加一个文档非常简单,可以使用 JSON 对象添加一个文档也可以提交一个对象数组。
会检查每个文档对应的必须字段,任何文档缺失字段都会拒绝整个请求。

请求URL参数:

  • index(required): string(Index)

请求体结构: application/json

  • property name*: 字符串数组或字符串

Responses

1. 200 标准Lnx返回,有简单的确认信息

响应体类型: application/json

  • status(required): 整形(状态)
  • data(required): 字符串或对象(数据)

    2. 400 索引不存在

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(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 }

  1. <a name="rn79f"></a>
  2. ### 删除指定文档
  3. 文档只能通过指定条件删除,你需要确保条件是唯一的,否则这个方法会删除多个文档。<br />注意:只有快速字段可以起作用,所以最好是使用唯一的ID或使用文档ID的 `_id` 字段。
  4. 请求URL参数:
  5. - index(required): string(Index)
  6. 请求体结构: application/json
  7. - property name*: 字符串数组或字符串
  8. <a name="HVctF"></a>
  9. #### Responses
  10. <a name="HGbDI"></a>
  11. ##### 1. 200 标准Lnx返回,有简单的确认信息
  12. 响应体类型: application/json
  13. - status(required): 整形(状态)
  14. - data(required): 字符串或对象(数据)
  15. <a name="jUfJO"></a>
  16. ##### 2. 400 索引不存在
  17. 响应体类型: application/json
  18. - status(required): 整形(状态)
  19. - data(required): 字符串或对象(数据)
  20. <a name="S2dBw"></a>
  21. ##### 3. 401 无权限操作
  22. 响应体类型: application/json
  23. - status(required): 整形(状态)
  24. - data(required): 字符串或对象(数据)
  25. <a name="nPuJ5"></a>
  26. ##### 4. 422 不能解析请求体
  27. <a name="P2Qd3"></a>
  28. #### 请求示例
  29. ```json
  30. // DELETE /indexes/{index}/documents
  31. // payload
  32. // content-type: application json
  33. []
  34. // Response
  35. // content-type: application/json
  36. {
  37. "status": 0,
  38. "data": "string
  39. }

清除所有文档

使用这个接口可以清除索引的所有文档

请求URL参数:

  • index(required): string(Index)

    Responses

    1. 200 标准Lnx返回,有简单的确认信息

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(required): 字符串或对象(数据)

    2. 400 索引不存在

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(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 }

  1. <a name="ueY8O"></a>
  2. ### 通过ID获取 文档
  3. 使用指定的 document_id 从索引获取一个文档
  4. 请求URL参数:
  5. - index(required): string(索引)
  6. - document_id(required): integer(文档ID)
  7. <a name="lVIrE"></a>
  8. #### Responses
  9. <a name="pLXlN"></a>
  10. ##### 1. 200 标准Lnx返回,有简单的确认信息
  11. 响应体类型: application/json
  12. - status(required): 整形(状态)
  13. - data(required): 字符串或对象(数据)
  14. <a name="xUMBQ"></a>
  15. ##### 2. 400 索引不存在
  16. 响应体类型: application/json
  17. - status(required): 整形(状态)
  18. - data(required): 字符串或对象(数据)
  19. <a name="pdscA"></a>
  20. ##### 3. 401 无权限操作
  21. 响应体类型: application/json
  22. - status(required): 整形(状态)
  23. - data(required): 字符串或对象(数据)
  24. <a name="l0pVp"></a>
  25. ##### 4. 422 不会产生此错误
  26. <a name="ko2ch"></a>
  27. #### 请求示例
  28. ```json
  29. // GET /indexes/{index}/documents/{document_id}
  30. // payload
  31. // content-type: application json
  32. []
  33. // Response
  34. // content-type: application/json
  35. {
  36. "status": 0,
  37. "data": "string
  38. }


执行搜索

添加完文档就可以准备开始搜索了!
Lnx为搜索索引提供了4种主要方式:

  • 一般 normal 这不是类型宽容的快速查询解析系统,但对自定义用户查询非常强大,比如日志查询。
  • 模糊 fuzzy 模糊查询会忽略标准解析器可能会处理的自定义查询系统,但条件类型是宽容的。
    • 如果指定的索引设置了 use_fast_fuzzytrue,将会使用模糊查询系统。
  • 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): 整形(状态)
  • data(required): 字符串或对象(数据)

    2. 400 索引不存在

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(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 } }

  1. <a name="LHP64"></a>
  2. ## Lnx 安全
  3. 通常 lnx是在 api 后面或有反向代理,但还是强烈建议为 Lnx 开启 token 令牌认证,的确会有错误会发生。<br />你是幸运的,Lnx为你提供了一个简单的可以自定义的权限认证系统。<br />当你第一次配置权限你需要在启动 lnx 时为cli传递一个参数 `--super-user-key <key>`,这不仅是你创建新的token来访问接口也是控制 lnx 是否启用权限认证。<br />向接口传递认证码需要在请求头使用如下格式:
  4. ```json
  5. 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 的标志来计算出你需要的权限整数值。例如,如果我位希望令牌能够修改文档和搜索索引,可以如下计算:

  1. permissions = 1 << 2 | 1 << 1

创建令牌

按指定的元数据创建新的访问令牌

请求体结构: application/json

  • permissions(required): 整数(权限)
  • user: 字符串(用户)
  • descrioption: 字符串(描述)
  • allowed_indexes: 字符串数组(允许的索引)

Responses

1. 200 返回包含令牌和其它元数据的对象

响应体类型: application/json

  • status(required): 整形(状态)
  • data(required): 对象(TokenData)

    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” } }

  1. <a name="mu5oH"></a>
  2. ### 废除所有令牌
  3. 废除所有访问令牌
  4. <a name="Y270z"></a>
  5. #### 警告
  6. 此功能只适用于紧急情况。运行此命令会删除所有访问令牌包括超级管理员,造成的后果由你自己承担。
  7. <a name="AIFtJ"></a>
  8. #### Responses
  9. <a name="HzdPK"></a>
  10. ##### 1. 200 标准确认信息
  11. 响应体类型: application/json
  12. - status(required): 整形(状态)
  13. - data(required): 字符串或对象(数据)
  14. <a name="jUffh"></a>
  15. ##### 2. 401 无权限操作
  16. 响应体类型: application/json
  17. - status(required): 整形(状态)
  18. - data(required): 字符串或对象(数据)
  19. <a name="GZpcL"></a>
  20. ##### 4. 422 不能解析请求体
  21. <a name="mvBA9"></a>
  22. #### 请求示例
  23. ```json
  24. // DELETE /auth
  25. // Response
  26. // content-type: application/json
  27. {
  28. "status": 0,
  29. "data": "string"
  30. }

废除令牌

废除指定令牌,运行此命令后再次使用当前令牌的请求都会被拒绝

Responses

1. 200 标准确认信息

响应体类型: application/json

  • status(required): 整形(状态)
  • data(required): 字符串或对象(数据)

    2. 400 Url中指定的令牌不存在

    响应体类型: application/json

  • status(required): 整形(状态)

  • data(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” }

  1. <a name="j6SpS"></a>
  2. ### 编辑令牌
  3. 编辑指定令牌的权限和元数据,请求体数据会替换所有字段,设置或移除字段
  4. 请求体结构: application/json
  5. - permissions(required): 整形数字(权限)
  6. - user: 字符串(用户)
  7. - description: 字符串(描述)
  8. - allowed_indexes: 字符串数组(允许的索引)
  9. <a name="eTGGM"></a>
  10. #### Responses
  11. <a name="Vg36x"></a>
  12. ##### 1. 200 返回令牌及其它元数据
  13. 响应体类型: application/json
  14. - status(required): 整形(状态)
  15. - data(required): 字符串或对象(数据)
  16. <a name="H6vhM"></a>
  17. ##### 2. 400 Url中指定的令牌不存在
  18. 响应体类型: application/json
  19. - status(required): 整形(状态)
  20. - data(required): 字符串或对象(数据)
  21. <a name="H9nV4"></a>
  22. ##### 3. 401 无权限操作
  23. 响应体类型: application/json
  24. - status(required): 整形(状态)
  25. - data(required): 字符串或对象(数据)
  26. <a name="kY0uT"></a>
  27. ##### 4. 422 请求体解析失败
  28. <a name="VFbmg"></a>
  29. #### 请求示例
  30. ```json
  31. // POST /auth/{token}/edit
  32. // Request
  33. // content-type: application/json
  34. {
  35. "permissions": 0,
  36. "user": "string",
  37. "description": "string",
  38. "allowed_indexes": ["string"]
  39. }
  40. // Response
  41. // content-type: application/json
  42. {
  43. "status": 0,
  44. "data": "string"
  45. }

优化索引

了解你的工作量

并不是每一组数据都有相同的最佳配置,在选择配置时,注意以下几点:

大型数据集(数百万以上数据集)

搜索大型数据集可以设置更多的读取器线程和更少的最大并发量,而更少的读取器线程和更多的并发线程会有负面影响,即一次以非常缓慢的速度运行许多搜索,而不是快速地运行少量搜索。

小型数据集(几千个数据集)

较小的数据集通过不能很好的利用大量的读取线程,这是因为数据没有被分割成足够的段来充分利用并行计算。

通常对于较小的数据集,最好是更高的并发性和更少的读取线程。

例如,示例中的 moviews.json 数据集大致优化为1 或 2个读取器线程和 n*3 个最大并发数,其中 n 中机器上的 CPU 核心数。也可以根据 CPU 的时钟速度进行调整,所以在确认配置之前仍要进行基准测试。