55

使用Elasticsearch7 java api实现pdf全文检索 - 海中灯塔

 4 years ago
source link: https://www.cnblogs.com/haizhongdenta/p/11496433.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用Elasticsearch7 java api实现pdf全文检索

前提:pdf的内容是文字形式而不是图片形式!

       Elasticsearch实现pdf的全文检索,原理是将pdf转换为Base64,然后提取pdf的文字内容然后将其存储起来.

       Elasticsearch已有相关Api提供,也给出了例子.链接如下:

       7.0 java api 例子

       我们来解读以下

//定制一个管道,用于将Base64转换为文字形式

PUT _ingest/pipeline/attachment
{
  "description" : "Extract attachment information",  //管道的描述
  "processors" : [
    {
      "attachment" : {
        "field" : "data"        //配置在哪个字段获取Base64数据,然后进行转换
      }
    }
  ]
}


//后面我们索引文档的时候 ?pipeline=attachment,就要指定这个参数,表明索引一个文档的时候要
使用这个管道

PUT my_index/_doc/my_id?pipeline=attachment
{
  "data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=" //base64数据
}

那么获取那篇刚刚索引的数据,返回的json就为

"attachment": {
      "content_type": "application/rtf",
      "language": "ro",
      "content": "Lorem ipsum dolor sit amet",
      "content_length": 28
    }

其中content就是转换后的文字

注意,上述操作的前提之下是装了ingest-attachment插件,可以再es的根目录下直接运行下面的命令进行安装

./bin/elasticsearch-plugin install ingest-attachment

二. Java Api 7.0的实现

我pdf都存储在远程服务器上,以https://*******.pdf路径进行存储着,所以如果你跟我一样,必须先根据http链接获取这个pdf然后转换为Base64,代码如下

 public static String pdfToBase64(String contentpath) throws IOException {
        InputStream is = null;
        String url = contentpath;
        URL url2 = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) url2.openConnection();
        conn.setDoInput(true);
        conn.connect();
        is =  conn.getInputStream();
        
         // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        byte[] data = null;
        // 读取图片字节数组
        try {
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100];
            int rc = 0;
            while ((rc = is.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            data = swapStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return new BASE64Encoder().encode(data).replace("\n", "").replace("\r", "");
    }

这个代码你放在一个Util类中直接调用就行,如果你是pdf存储在本地,直接通过File获取然后转换,网上有很多,在这就不说了.

//将http链接作为参数
String base64Contentpath = Base64Util.pdfToBase64("http://******.pdf");

然后我们就可以将其存在一个pdf的索引中,但是别忘记指定管道

    RestHighLevelClient esClient = esClient();
    Map<String,Object> jsonMap = new HashMap<>();

    jsonMap.put("base64Contentpath", base64Contentpath);


    IndexRequest request = new IndexRequest("pdf")
                                .setPipeline("管道名称")   //这里就是前面通过json创建的管道
                                .source(jsonMap);  

    esClient.index(request, RequestOptions.DEFAULT);   //执行

 这样我们就对pdf的内容进行提取然后索引到Elasticsearch中了.后面怎么搜索就不要再说了

 这里我只贴出了关键代码,如果有什么不懂的或者是有什么错误,请在文章的评论下方指出来


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK