【上海网络优化公司】使用Docker和Elasticsearch搭建全文本搜索引擎应用

发布时间:2019-09-27 14:40:39访问人数:作者:

喜欢记得转发关注哟


给应用添加快速、灵活的全文本搜索对谁都不是一件容易的事情。许多主流数据库,如PostgreSQL和MongoDB,受限于查询和索引结构,只提供基础文本搜索能力。为了提供高效全文本搜索一般都需要一个独立的数据库。Elasticsearch正是这样一个能够提供灵活性和快速全文本搜索能力的开源数据库。


本文采用Docker来设置依赖环境。Docker是目前较常见的容器化引擎,Uber、Spotify、ADP和Paypal都是用这个技术,它的优势在于与操作系统无关,可以运行在Windows、macOS和Linux之上——写操作指南很容易。如果从来没有用过Docker也没问题,本文会详细提供配置文件。


本文也分别采用Node.js采(用Koa框架)和Vue.js创建搜索API和前端Web应用。


1. 什么是Elasticsearch


现代应用中全文本检索是高请求负载的应用。搜索功能也是比较困难完成的功能(许多大众网站都有subpar功能,但不是返回很慢就是返回结果不准确),大部分原因是因为底层数据库:许多标准关系型数据库只能提供基本字符串匹配功能,而对CONTAINS或者LIKE SQL查询只能提供有限支持。


而本文提供的搜索应用能够提供:


快速:查询结果应该实时返回,提高用户体验。


灵活:根据不同数据和使用场景,可以调整搜索过程。


较佳建议:对于输入错误,返回较可能的结果。


全文本:除了搜索关键词和标签之外,希望能够搜索到所有匹配文本。


实现以上要求的搜索应用,较好采用一个为全文本检索优化的数据库,这也是本文采用Elasticsearch的原因。Elasticsearch是一个用Java开发的,开源的内存数据库,较开始是包含在Apache Lucene库中。以下是一些官方给出的Elasticsearch使用场景:


Wikipedia使用Elasticsearch提供全文检索,提供高亮显示、search-as-you-type和did-you-mean建议等功能。


Guardian使用Elasticsearch将访问者社交数据整合反馈给作者。


Stack Overflow将位置信息和more-like-this功能与全文本检索整合提供相关问题和答案。


GitHub使用Elasticsearch在一千三百亿行代码中进行搜索。


Elasticsearch有什么独特之处


本质上,Elasticsearch通过使用反向索引提供快速和灵活的全文本搜索。


“索引”是一种在数据库中提供快速查询和返回的数据结构。数据库一般将数据域和相应表位置生成索引信息。将索引信息存放在一个可搜索的数据结构中(一般是B-Tree),数据库可以为优化数据请求获得线性搜索响应(例如“Find the row with ID=5”)。


可以把数据库索引看做学校图书馆卡片分类系统,只要知道书名和作者,就可以准确告诉查找内容的入口。数据库表一般都有多个索引表,可以加速查询(例如,对name列的索引可以极大加速对特定name的查询)。


而反向索引工作原理与此完全不同。每行(或者每个文档)的内容被分拆,每个入口(本案例中是每个单词)反向指向包含它的文档。


反向索引数据结构对查询“football”位于哪个文档这种查询非常迅速。Elasticsearch使用内存优化反向索引,可以实现强大和客制化全文本检索任务。


2. 项目安装


2.0 Docker


本文使用Docker作为项目开发环境。Docker是一个容器化引擎,应用可以运行在隔离环境中,不依赖于本地操作系统和开发环境。因为可以带来巨大灵活性和客制化,许多互联网公司应用都已经运行在容器中。


对于作者来说,Docker可以提供平台一致性安装环境(可以运行在Windows、macOS和Linux系统)。一般Node.js、Elasticsearch和Nginx都需要不同安装步骤,如果运行在Docker环境中只需要定义好不同配置文件,就可以运行在任何Docker环境。另外,由于应用各自运行在隔离容器中,与本地宿主机关系很小,因此类似于“但是我这可以运行啊”这种排错问题就很少会出现。


2.1 安装Docker和Docker-Compose


本项目只需要Docker和Docker-Compose环境。后者是Docker官方工具,在单一应用栈中编排定义多个容器配置。


安装Docker——


安装Docker Compose——


2.2 设置项目安装目录


创建一个项目根目录(例如guttenberg_search),在其下定义两个子目录:


public——为前端 Vue.js webapp存放数据。


server——服务器端Node.js 源文件。


2.3 添加Docker-Compose配置文件


下一步,创建docker-compose.yml文件,定义应用栈中每个容器的配置:


gs-api——Node.js 容器后端应用逻辑.


gs-frontend——为前端webapp提供服务的Nginx容器


gs-search——存储搜索数据的Elasticsearch容器


version: '3'services:api: # Node.js Appcontainer_name: gs-apibuild: .ports: - "3000:3000" # Expose API port - "9229:9229" # Expose Node process debug port (disable in productionenvironment: # Set ENV vars - NODE_ENV=local - ES_HOST=elasticsearch - PORT=3000volumes: # Attach local book data directory - .books:usrsrcappbooksfrontend: # Nginx Server For Frontend Appcontainer_name: gs-frontendimage: nginxvolumes: # Serve local "public" dir - .public:usrsharenginxports: - "8080:80" # Forward site to localhost:8080elasticsearch: # Elasticsearch Instancecontainer_name: gs-searchimage: docker.elastic.coelasticsearchelasticsearch:6.1.1volumes: # Persist ES data in seperate "esdata" volume - esdata:usrshareelasticsearchdataenvironment: - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - discovery.type=single-nodeports: # Expose Elasticsearch ports - "9300:9300" - "9200:9200"volumes: # Define seperate volume for Elasticsearch dataesdata:<pre>


此文件定义应用栈,而不需要在本地宿主机安装Elasticsearch、Node.js、或者Nginx。每个容器都对宿主机开放相应端口,以便从宿主机访问和排错Node API,Elasticsearch实例和前端应用。


2.4 添加Dockerfile


本文使用官方的Nginx和Elasticsearch镜像,但是需要重新为Node.js创建自己的镜像。


在应用根目录定义一个简单的Dockerfile配置文件。


# Use Node v8.9.0 LTSFROM node:carbonSetup app working directoryWORKDIR usrsrcappCopy package.json and package-lock.jsonCOPY package*.json .Install app dependenciesRUN npm installCopy sourcecodeCOPY . .Start appCMD [ "npm", "start" ]<pre>


此Docker配置文件中将应用源码拷贝进来,安装了NPM依赖包,形成了自己的镜像。同样需要添加一个.dockerignore文件,避免不需要的文件被拷入。


node_modulesnpm-debug.logbookspublic<pre>注意:不需要将node_modules拷入,因为我们后续要用npm install来安装这些进程。如果拷贝node_modules到容器中容易引起兼容性问题。例如在macOS上安装bcrypt包,如果将此module拷入Ubuntu容器就会引起操作系统不匹配问题。


2.5 添加基础文件


测试配置文件前,还需要往应用目录拷入一下占位文件。在publicindex中加入如下基础配置信息:


><body>Hello World From The Frontend Container<body><><pre>


下一步,在serverapp.js中加入Node.js的应用文件。


{if (err console.error(errconsole.log(`App Listening on Port ${port}`}<pre>


较后,加入package.json节点配置文件:


{"name": "guttenberg-search","version": "0.0.1","description": "Source code for Elasticsearch tutorial using 100 classic open source books.","scripts": {"start": "node --inspect=0.0.0.0:9229 serverapp.js"},"repository": {"type": "git","url": "git+ "","license": "MIT","bugs": {"url": " " {"elasticsearch": "13.3.1","joi": "13.0.1","koa": "2.4.1","koa-joi-validate": "0.5.1","koa-router": "7.2.1"}}<pre>


此文件定义应用开始命令和Node.js依赖包。


注意:不需要特意运行npm install,容器创建时候会自动安装依赖包。


2.6 开始测试


都准备好了,接下来可以测试了。从项目根目录开始,运行docker-compose,会自动创建Node.js容器应用。


运行docker-compose up启动应用:


注意:这一步可能会运行时间比较长,因为Docker可能需要下载基础镜像。以后执行速度会很快,因为本地已经有了基础镜像。


访问localhost:8080,应该看到如下图输出“hello world”。


访问localhost:3000验证服务器端返回“hello world”信息。


较后,访问localhost:9200确认Elasticsearch是否运行,如果正常,应该返回如下输出:


{"name" : "SLTcfpI","cluster_name" : "docker-cluster","cluster_uuid" : "iId8e0ZeS_mgh9ALlWQ7-w","version" : {"number" : "6.1.1","build_hash" : "bd92e7f","build_date" : "2019-12-17T20:23:25.338Z","build_snapshot" : false,"lucene_version" : "7.1.0","minimum_wire_compatibility_version" : "5.6.0","minimum_index_compatibility_version" : "5.0.0"},"tagline" : "You Know, for Search"}<pre>


如果所有URL输出都正常,恭喜,整个应用框架可以正常工作,下面开始进入真正有趣的部分了。


赞+1

华夕网络 版权所有 Copyright © 2012-2018 www.jswlgs.com All Rights Reserved .   备案号:沪ICP备15005556号-3    网站地图    代理商查询

  • QQ
  • 电话
  • 首页
  • 留言
  • 返回顶部
  • zxly.png