实战:Nodejs+Mongodb+Elasticsearch 实现简单的搜索
来源:互联网 发布:python自然语言处理包 编辑:程序博客网 时间:2024/06/07 02:55
在网站建立初期,我们提供的搜索服务很多都是基于数据库的模糊搜索,在性能和可用性上多少会有所缺失,所以在网站发展壮大后,就不得不增强搜索功能。elasticsearch 的基本功能就已经足够一般的搜索需求。本文将介绍,如何使用 nodejs + mongodb + es 实现一个简单而强大的全文搜索功能,以提高网站搜索体验。
基本架构图
数据存储在 mongodb
使用 elasticsearch 作为搜索数据库
nodejs 用官方客户端 elasticsearch-js 请求 elasticsearch
使用 mongo-connector 同步 mongodb 的数据到 elasticsearch
前端随便请求一下
elasticsearch
本文使用的是 elasticsearch-rtf,这个库使用的是 elasticsearch 5.1 版本,并且预装了一些常用插件,比如常用分词器。
在安装完 java 环境后,就可以直接运行 elasticsearch 目录里的 bin/elasticsearh。不过在虚拟机中,会有各种像内存不足,文件描述符限制等问题。所以在虚拟机中,我们需要修改一些配置:
修改 config/jvm.options 里的 jvm 内存为 512m
# Xms represents the initial size of total heap space# Xmx represents the maximum size of total heap space#-Xms2g#-Xmx2g-Xms512m-Xmx512m
修改文件描述符上限,需要 root 权限,然后运行
ulimit -n 65536
为了让别的机器能连上 elasitcsearch 机器,需要把 config/elasticsearch.yml 里的 network.host 修改为 0.0.0.0。另外,还需要运行如下命令
sysctl -w vm.max_map_count=262144
不然会报 vm.max_map_count 不足的错误。
mongodb
安装就好,没有坑
mongo-connector
mongo-connector 是一个 python 编写的,用来复制 mongodb 中数据到各种搜索数据库的工具,支持 elasticsearch。
使用这个库前,要先在 mongodb 中设置 replSet,具体可以查看这里。
另外,在运行中需要用到 elastic_doc_manager 这个库,需要另外安装,在他的 README 里没有明确指明需要另外安装,具体可以查看这里。
最后,运行:
mongo-connector -m localhost:27017 -t localhost:9200 -d elastic_doc_manager
mongo-connector 会把 mongodb 里的数据同步到 elasticsearch。
测试数据
测试数据使用 Faker-zh-cn.js 生成。这个库是 faker.js 的中文版。代码如下:
const { MongoClient } = require('mongodb')const faker = require('faker-zh-cn')const DB_URL = 'mongodb://192.168.134.125:27017/test'faker.locale = 'zh_CN'const insertData = function(db, callback) { let collection = db.collection('data') let data = [] for (let i = 0; i <= 1000; i++) { data.push({ "name": faker.Name.findName(), "address": `${faker.Address.city()},${faker.Address.streetName()},${faker.Address.streetAddress()}`, "description": faker.Lorem.paragraph() }) } collection.insert(data, function(err, result) { if(err) { console.log('Error:'+ err) return } console.log('success') callback && callback(result) })}MongoClient.connect(DB_URL, function (err, db) { if (err) { return console.log(err) } console.log('连接成功') insertData(db)})
替换分词器
生成测试数据后,使用 elasticsearch 的 rest api 测试搜索,发现搜索结果并不理想。比如使用查询条件 q=王者农药,出来的结果除了王者、农药相关的结果,连包含王、者、农或药的结果都出来了,说明搜索默认对中文以字为单位分词,我们需要替换分词器。
elasticsearch-analysis-ik 是一个流行的中文分词库,在 elasticsearch-rtf 中已经集成,可直接使用。
更换分词器需要对 elasticsearch 的映射重定义。使用 elasticsearch 的 rest api 进行设置,会报错,大概意思就是已经存在数据的索引的映射不能被修改,所以要另辟蹊径。
后来查到,只需要根据旧的索引和类型,重新建立一个索引,然后把想要修改的索引,reindex 到新索引即可。新索引的映射带上了 analyzer: "ik_smart" 的声明,就可以用上这个分词器了。
最后,搜索结果变得正常了一点,只会出现王者和农药相关的结果了,说明分词器起效了。
nodejs 代码
用的 express 随便意思一下
const { Client } = require('elasticsearch')const INDEX = 'index'const express = require('express')const app = express()let client = new Client({ host: '192.168.134.125:9200', log: 'trace'})app.use(express.static(__dirname + '/public'))app.get('/', (req, res) => { res.send('Hello World')})app.get('/search/:keyword?', (req, res) => { client.search({ q: req.params.keyword, index: INDEX, size: 999 }).then(function (body) { var hits = body.hits.hits res.send(hits) }, function (error) { console.trace(error.message) })})console.log('listening port: 3000')app.listen(3000)
结果
前端就是一个简单的页面,调用 nodejs 的接口,看起来是这样的
最后
本人才疏学浅,如有纰漏,还望指正。
参考 :
https://segmentfault.com/a/1190000003773614
- 实战:Nodejs+Mongodb+Elasticsearch 实现简单的搜索
- elasticsearch+mongodb 搜索框架
- NodeJS+Mongodb数据库实现简单在线应用程序
- 实战开发:nodejs(express)+mongodb+........简单博客系统代码
- 分享一段mysql,mongodb 实现LBS搜索的简单代码
- nodejs+express+mongodb简单的例子
- nodejs+express+mongodb简单的例子
- nodejs+express+mongodb简单的例子
- Nodejs+Extjs+Mongodb开发第二天 Mongodb的简单使用
- 构建垂直搜索引擎 本课程带领大家实现一个简单的垂直搜索引擎网站,使用nodejs、python、elasticsearch实现的。
- nodejs + mongodb 实现用户登录的资源
- logstash-out-mongodb实现elasticsearch到Mongodb的数据同步
- 一个简单的nodeJS实现
- RPC的nodejs简单实现
- elasticsearch实现分类搜索
- 简单的搜索实现
- 一个简单的nodejs+express+mongodb的英文教程
- nodejs+mongodb写的一个简单的登录注册
- 使用Javascript 实现 分享到 新浪微博 QQ 空间等
- 微信小程序dom操作的替代思路
- C/C++:string.c_str()
- $("#loginname").tips和jQuery中 的ajax
- hdu 3535 混合背包
- 实战:Nodejs+Mongodb+Elasticsearch 实现简单的搜索
- HBuilder打包Vue-cli构建的APP
- POJ1274 The Perfect Stall
- Java菜鸟学习日记1
- Python 函数参数魔法
- stderr和stdout(printf、fprintf、sprintf)
- YANG语法
- 矩形面积相交
- mysql 字符串转数字并排序