文件检索

ESQL 提供了 文件存储、文件检索、文件获取 等相关语法和接口

实现原理

ESQL的文件检索是通过 ES 的 mapper-attachments 插件实现的。 其内部使用 Tika 来提取文件内容, Tika 几乎支持所有常用的文件格式, 并且文件格式识别不依赖扩展名。

使用文件检索功能前, 要为所有ES节点安装 ElasticSearch插件mapper-attachments

关于文件获取

虽然ES可以将文件内容存入_content字段中, 但是select结果会带出文件内容 (结果集大的时候严重影响性能)。

ES中不存储文件内容 (_content 设置为 _source excludes)时, 虽然可以设置 file_filed 为 {‘type’: ‘string’, ‘store’: True} 再通过 GET index_doc_type id fields=file_filed_name 来获取文件内容, 但该内容只是提取后的纯文本内容。

故 ESQL 采用了文件外部独立存储的方式

系统配置

conf/esql.yml 中文件检索相关配置:

# -------------------- 文件服务器 --------------------
file_server: {
  # 文件服务器类型   local: ESql服务器硬盘
  type: local,
  # 目录地址, type为local时必须指定(使用相对路径时,当前目录为esql安装目录)
  path: files/
}

目前只支持本地文件系统, 以后会加入网络文件系统支持

目录地址 (path) 可以使用绝对路径, 相对路径时对应的是esql安装目录

设置表结构

ESql 提供了专门的 FILE 字段:

-- CREATE TABLE file_test(my_file FILE {analyzer=ik});  自定义分词器(中文分词ik)
CREATE TABLE file_test(my_file FILE);

FILE 类型比较特殊, 字段必须通过 CREATE 语句创建, 不能 INSERT 时自动生成

ESQL 支持同一个表通过多次 CREATE 来增加字段

插入文件

INSERT INTO file_test(my_file()) values(%s);

FLUSH file_test;

FILE 类型的字段要加双括号;values值(%s)由ESQL提供的接口生成: Python file_set 、 Java fileSet

检索文件

-- 根据内容检索
SELECT * FROM file_test WHERE my_file LIKE 'xxxx';
-- 根据文件名称检索
SELECT * FROM file_test WHERE my_file.name = 'xxx.pdf';
-- 根据文件类型检索
SELECT * FROM file_test WHERE my_file.content_type = 'application/pdf';
-- 根据文件大小检索
SELECT * FROM file_test WHERE my_file.content_length < 256;

由于ES文件索引(分词)时会把英文单词中的大写字母转成小写, 用英文单词检索文件内容的时请一律使用小写字母

提取文件

提取文件接口: Python file_get 、 Java fileGet

ESQL 的访问控制同样适用于该接口, 如果用户要获取某表FILE字段对应的原始文件, 必须拥有该表的读权限.