继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

使用Elasticsearch搭建一个文件搜索系统(带界面)

点火三周
关注TA
已关注
手记 5
粉丝 1
获赞 11

接触ELK这么久,一直都在日志分析和系统运维方面兜圈圈。今天来玩转一下搜索技能,填补一下这方面的空白。主要也是好多天没更新博客了,来写一篇

何为文件搜索系统?其实简单一点,就可以想象为一个带用户界面的grep,可以根据你提供的关键字查询包含该内容的文件。与grep一样,该系统应该能返回包含该搜索条件的文件名,行号和具体内容等,同时应该支持高亮。与grep只支持正则表达式不一样的是,以elasticsearch为基础的搜索系统,能支持更多的搜索模式和匹配模式。当然,我们的系统肯定是比grep提供更多的功能。

基本需求

特点如下:

  • 基于web的用户界面,使用浏览器就可以直接访问
  • 可以对文件内容进行搜索和匹配,并且返回文件基本信息和关键字高亮,并提供链接远程打开文件
  • 支持各种富文本内容,包括ppt, pdf等
  • 可以监控文件的变化,当文件有增删改之后,能够重新索引文件

我们先看看最终的效果:
图片描述

任务分解

再简单分解一下所需要的技术:

  • web前端:
    • UI:提供搜索条、展示搜索结果面板和文件打开链接
    • 逻辑:将搜索内容组装为elasticsearch的搜索语句发送到后端,并且将response进行合理的处理
  • web后端:
    • web服务器提供web API服务
    • 同时对接elasticsearch,作为中间件,处理 前端请求 <——> elasticsearch 之间的互动
    • web文件服务器,提供静态文件的访问
  • 数据库:
    • elasticsearch作为数据库,包含文件的索引和基本信息
  • 文件监控与索引
    • 需要对特定目录下的文件进行监控和索引
    • 任何的增删改动作都触发文件的索引(把文件索引到elasticsearch当中,以便可以搜索)

咋一看貌似挺复杂的。但如同所有的软件开发,只要不是特别创新的功能,总会有人已经帮你踩好了坑,我们要做的是找到合适的轮子而不是重复造轮子(一开始也是打算自己把这套东西都实现了,结果一google,啥都有)。

为了更方便的集成搜索服务到你的APP或者网站,elastic提供了一套search UI (官网)。只需要寥寥几行代码,即可内嵌一个非常美观的search套件到你的应用或者网站当中。我们的实现也主要是基于这个search UI.

具体的代码可查地址

web 前端

但是这套工具的是默认你使用App search或者site search服务的,其接口设置是使用一个connector与远程的search服务进行交互。
图片描述
如果我们没有购买类似的服务,只能修改这个代码为使用本地的elasticsearch。具体的示例在github上也能找到,我们的代码也是基于这个example

所需的component大致如下:

package.json:

{
  "name": "elasticsearch-example",
  "version": "0.8.0",
  "private": true,
  "proxy": "http://localhost:9000",
  "dependencies": {
    "@elastic/react-search-ui": "0.8.0",
    "@elastic/react-search-ui-views": "0.8.0",
    "@elastic/search-ui": "0.8.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-scripts": "3.0.1"
  },
  "scripts": {
    "start": "npm-run-all --parallel start:app start:server",
    "start:app": "react-scripts start",
    "start:server": "netlify-lambda serve ./functions",
    "build": "npm-run-all --parallel build:**",
    "read": "read",
    "build:app": "react-scripts build",
    "build:functions": "netlify-lambda build ./functions"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "encoding": "^0.1.12",
    "netlify-lambda": "^1.4.7",
    "node-fetch": "^2.5.0",
    "npm-run-all": "^4.1.5"
  }
}

需要重写一下autoComplete.js以适配我们自己的数据格式
图片描述

web 后端

以上项目已经实现了一个nodeJs的后端,直接启动npm start即可,但需要注意的是,需要通过环境变量指定elasticsearch的url,即完整的命令是:
ELASTICSEARCH_HOST=http://localhost:9200 npm start

索引替换

前面我们提到后端需要对接elasticsearch,作为中间件,处理 前端请求 <——> elasticsearch 之间的互动,这部分代码框架已经实现了,我们要做的是把索引替换为我们自己的索引。

图片描述

文件监控与索引

这里,我们使用 fscrawler 就能完全满足我们的需求。因为文档很齐全,我这里就不一一解释了。
我这里监控了一个目录/Users/Documents/AWS

ls -l
total 24736
-rw-r--r--@ 1 lex  staff    22523  6 10 15:20 2019年风险管理制度学习活动-量化风险-学习资料.docx
-rw-r--r--@ 1 lex  staff   567176  6 10 15:20 AWS_Certified_Solutions_Architect_Associate_Feb_2018_ Exam_Guide_v1.5.2.pdf
-rw-r--r--@ 1 lex  staff   389035  6 10 15:20 AWS_Certified_Solutions_Architect_Associate_Sample_Questions.pdf
-rw-r--r--@ 1 lex  staff   195516  6 10 15:20 AWS_certified_solutions_architect_associate_blueprint.pdf
-rw-r--r--@ 1 lex  staff  2338541  6 10 15:20 ES多数据同步之道分享.key

则对应的配置文件,简单的可以设置为:

---
name: "files"
fs:
  url: "/Users/Documents/AWS/"
  update_rate: "15m"
  excludes:
  - "*/~*"
  json_support: false
  filename_as_id: false
  add_filesize: true
  remove_deleted: true
  add_as_inner_object: false
  store_source: false
  index_content: true
  attributes_support: false
  raw_metadata: false
  xml_support: false
  index_folders: true
  lang_detect: false
  continue_on_error: false
  ocr:
    language: "eng"
    enabled: true
    pdf_strategy: "ocr_and_text"
  follow_symlinks: false
elasticsearch:
  nodes:
  - url: "http://127.0.0.1:9200"
  bulk_size: 100
  flush_interval: "5s"
  byte_size: "10mb"

以下是该工具写入到es的对象为:

{
  "_index": "files",
  "_type": "_doc",
  "_id": "f982d250b791df3ea3b1e0c1b184e283",
  "_version": 18,
  "_score": null,
  "_source": {
    "content": "\n   AWS Certified Solutions Architect – \nAssociate ...",
    "meta": {
      "author": "Barnosky, Timothy",
      "date": "2018-02-08T06:13:32.000+0000",
      "language": "en-US",
      "format": "application/pdf; version=1.5",
      "creator_tool": "Microsoft Word 2013",
      "created": "2018-02-08T06:13:32.000+0000"
    },
    "file": {
      "extension": "pdf",
      "content_type": "application/pdf",
      "created": "2019-04-03T03:31:49.000+0000",
      "last_modified": "2019-04-03T03:31:49.000+0000",
      "last_accessed": "2019-06-05T08:08:22.000+0000",
      "indexing_date": "2019-06-05T08:08:22.479+0000",
      "filesize": 567176,
      "filename": "AWS_Certified_Solutions_Architect_Associate_Feb_2018_ Exam_Guide_v1.5.2.pdf",
      "url": "file:///Users/caishichao/Documents/AWS/AWS_Certified_Solutions_Architect_Associate_Feb_2018_ Exam_Guide_v1.5.2.pdf"
    },
    "path": {
      "root": "431c7636e585854c841c8e88a25ea39",
      "virtual": "AWS_Certified_Solutions_Architect_Associate_Feb_2018_ Exam_Guide_v1.5.2.pdf",
      "real": "/Users/caishichao/Documents/AWS/AWS_Certified_Solutions_Architect_Associate_Feb_2018_ Exam_Guide_v1.5.2.pdf"
    }
  },
  "sort": [
    -9223372036854776000
  ]
}

UI上可以通过读取contentfilepath的内容进行必要的展示

具体需要修改buildState.js里面的内容进行适配。
图片描述

文件下载

我们可以使用nginx或者其他工具为文件目录提供一个web访问的解决方案,当搜索某个关键字被匹配后,根据文件信息,构造一个下载路径,提供文件下载

结语

其实这个博文我没有写得特别的详细,只是简单的总结一下思路,希望对大家有帮助

打开App,阅读手记
2人推荐
发表评论
随时随地看视频慕课网APP

热门评论

这部分源码能分享一下吗 万分感谢?

查看全部评论