Elasticsearch 支持 PDF 等文件搜索

前言

默认情况下 es 是不支持 pdf、doc 等文档的搜索的,但是可以通过安装 Ingest attachment plugin 插件来使得 es 提取通用格式的文件,从而可以实现搜索的功能。

安装与使用

安装 Ingest attachment plugin

安装很简单,通过 elasticsearch-plugin 可以直接进行安装

1
bin/elasticsearch-plugin install ingest-attachment

Ingest attachment plugin 允许 Elasticsearch 通过使用 Apache 文本提取库 Tika 提取通用格式(例如:PPT,XLS 和 PDF)的文件附件。Apache Tika 工具包可从一千多种不同的文件类型中检测并提取元数据和文本。所有这些文件类型都可以通过一个界面进行解析,从而使 Tika 对搜索引擎索引,内容分析,翻译等有用。需要注意的是,源字段必须是 Base64 编码的二进制,如果不想增加在 Base64 之间来回转换的开销,则可以使用 CBOR 格式而不是 JSON,并将字段指定为字节数组而不是字符串表示形式,这样处理器将跳过 Base64 解码。

创建 attachment pipeline

通过 kibana 的开发工具进行请求

1
2
3
4
5
6
7
8
9
10
11
PUT _ingest/pipeline/pdfattachment
{
"description": "Extract attachment information encoded in Base64 with UTF-8 charset",
"processors": [
{
"attachment": {
"field": "file"
}
}
]
}

返回结果:

1
2
3
{
"acknowledged" : true
}

表示创建成功,接下来就是验证上传 pdf 以及搜索功能了。

转换并上传PDF文件的内容到Elasticsearch中

对于 Ingest attachment plugin 来说,它的数据必须是 Base64 的。这里为了快速创建,我们通过一个 bash 脚本去处理用来测试的 pdf

1
2
3
4
5
6
7
8
9
!/bin/bash

encodedPdf=`cat sample.pdf | base64`

json="{\"file\":\"${encodedPdf}\"}"

echo "$json" > json.file

curl -X POST 'http://localhost:9200/pdf-test1/_doc?pipeline=pdfattachment&pretty' -H 'Content-Type: application/json' -d @json.file

上传成功会返回如下的结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"_index" : "pdf-test1",
"_type" : "_doc",
"_id" : "1oVSxHsB1ubIHqCXIbPU",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}

如果出现提示下述提示

1
2
3
4
5
{
"statusCode": 400,
"error": "Bad Request",
"message": "Payload content length greater than maximum allowed: 1048576"
}

说明上传的文件大小超过了 Kibana 默认的上限(默认 1M),修改 kibana 的配置 kibana.yml

1
server.maxPayloadBytes: "209715200"

查看索引并搜索

查看索引

通过下面的命令可以查看 pdf-test1 的索引情况:

1
GET pdf-test1/_search

结果如下图

其中 _source 里有个 content 字段,就是 pdf 的内容,结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
{
"_source": {
"file":"...",
"attachment": {
"date": "2021-08-18T07:29:34Z",
"content_type": "application/pdf",
"author": "author",
"language": "lt",
"title": "2021-07(copy)",
"content": "..."
}
}

其中 file 就是 base64 格式的内容,content 则包含了 pdf 的内容,如果不想要 file 则可以通过 remove processor 去除这个字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PUT _ingest/pipeline/pdfattachment
{
"description": "Extract attachment information encoded in Base64 with UTF-8 charset",
"processors": [
{
"attachment": {
"field": "file"
}
},
{
"remove": {
"field": "file"
}
}
]
}

搜索

通过在 kibana 的开发工具执行下述命令,验证一下搜索:

1
2
3
4
5
6
7
8
GET pdf-test1/_search
{
"query": {
"match": {
"attachment.content": "5G"
}
}
}

参考链接

Elasticsearch:如何对PDF文件进行搜索