自制搜索(elasticsearch安装,mongo-connector同步数据,python操作)

本文主要是介绍自制搜索(elasticsearch安装,mongo-connector同步数据,python操作),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

做一个搜索,以es为基础,数据存在mongodb


1:Elasticsearch

下载:

elasticsearch下载地址https://www.elastic.co/downloads/elasticsearch

安装:

修改elasticsearch-5.5.1/config/elasticsearch.yml

# 集群名称
cluster.name: myElasticsearch
# 节点名称
node.name: node001
# 0.0.0.0是为了让别的机器访问
network.host: 0.0.0.0
# 端口
http.port: 9200

命令:elasticsearch-5.5.1/bin/elasticsearch

浏览器:127.0.0.1:9200



2:Elasticsearch-head

修改elasticsearch-5.5.1/config/elasticsearch.yml

# 增加新的参数,这样head插件可以访问es
http.cors.enabled: true
http.cors.allow-origin: "*"


下载(需要git):

git clone git://github.com/mobz/elasticsearch-head.git


安装grunt(需要node和npm):

npm install -g grunt-cli
npm install -g grunt


修改head源码

elasticsearch-head/Gruntfile.js

connect: {server: {options: {port: 9100,hostname: '*',base: '.',keepalive: true}}}});
添加hostname: '*',


elasticsearch-head/_site/app.js

# 修改head的连接地址:
this.base_uri = this.config.base_uri || this.prefs.get("app-base_uri") || "http://localhost:9200";
# 把localhost修改成你es的服务器地址,如:
this.base_uri = this.config.base_uri || this.prefs.get("app-base_uri") || "http://x.x.x.x:9200";

安装elasticsearch-head(需要node和npm)

cd elasticsearch-head/

npminstall


启动:

grunt server


浏览器:127.0.0.1:9100


3:mongo-connector

mongo-connector需要开启MongoDB复制集

新建三个data文件夹

# replSet后面是复制集名称,port是端口,dbpath是data目录
# 第一个节点
sudo mongod --dbpath=/Users/zjl/mongodbdata/data1 --port 27018 --replSet rs0
# 第二个节点
sudo mongod --dbpath=/Users/zjl/mongodbdata/data2 --port 27019 --replSet rs0
# 第三个节点
sudo mongod --dbpath=/Users/zjl/mongodbdata/data3 --port 27020 --replSet rs0


进入mongo的shell

mongo 127.0.0.1:27018config = {"_id": "rs0",members: [{ "_id": 0,"host": "127.0.0.1:27018"},{ "_id": 1,"host": "127.0.0.1:27019"},{ "_id": 2,"host": "127.0.0.1:27020",arbiterOnly:true}]}
# arbiterOnly:true是这个节点是仲裁节点,据说这个很鸡肋,只需节点个数是单数就不需要了,仲裁节点不存数据# 进行初始化:
rs.initiate(config);# 查看配置信息
rs.conf();# 查看状态
rs.status();


安装mongo-connector

https://github.com/mongodb-labs/mongo-connector

pip install 'mongo-connector[elastic5]'


同步命令:mongo-connector -m 127.0.0.1:27018 -t 127.0.0.1:9200 -d elastic2_doc_manager

出现Logging to /xx/xx/mongo-connector.log.说明正常


现在我们在mongo主节点新建一个库,会马上同步到其它子节点,并且同步到elasticsearch


rs后面是端口号,27018是主节点,我在主节点新建一个库,马上就同步到子节点


也同步到了elasticsearch上,mongo的库是elasticsearch的索引,表是elasticsearch的type



4:python操作elasticsearch

https://www.elastic.co/guide/en/elasticsearch/client/python-api/current/index.html

pip install elasticsearch


百度,谷歌之类的搜索会对用户的输入进行关键词提取,去重,英文单词纠错

先往mongo添加一些数据



elasticsearch据说内部默认字符串相似度算法是TF-IDF,但是没有分词,不过elasticsearch有ik分词器的插件可以不需要自己手动实现,不过这里我用jieba分词,因为es搜索时内部的算法已经封装好了,而且字符串算法都那些套路,所以我对搜索结果再进行算法加工也没有太大的意义,所以我能做的就是在关键字进入es之前做一些处理,比如关键词提取,单词纠错,感觉能做很有限,毕竟搜索引擎到底怎么样的我不清楚


estest

|----enchant_py.py(单词纠错,网上找的)

|----EsQuery.py(elasticsearch操作)

|----flaskrun.py(flask服务)

|----dict.txt(jieba词库,发现分词结果不理想往里面添加词语,设置词频)

|----stop_words.txt(jieba的停用词,用于关键词提取)

|----big.txt(单词纠错用到的词库,这个太长了,找一个英英词典或者英文小说,如果效果不好,往里面添加你想要的词)


enchant_py.py

# -*- coding: utf-8 -*-
#__author__="ZJL"import re, collectionsdef words(text): return re.findall('[a-z]+', text.lower())def train(features):model = collections.defaultdict(lambda: 1)for f in features:model[f] += 1return modelNWORDS = train(words(open('big.txt').read()))alphabet = 'abcdefghijklmnopqrstuvwxyz'def edits1(word):n = len(word)return set([word[0:i] + word[i + 1:] for i in range(n)] +  # deletion[word[0:i] + word[i + 1] + word[i] + word[i + 2:] for i in range(n - 1)] +  # transposition[word[0:i] + c + word[i + 1:] for i in range(n) for c in alphabet] +  # alteration[word[0:i] + c + word[i:] for i in range(n + 1) for c in alphabet])  # insertiondef known_edits2(word):return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)def known(words): return set(w for w in words if w in NWORDS)def correct(word):candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]return max(candidates, key=lambda w: NWORDS[w])# print('thew => ' + correct('thew'))
# print('spak => ' + correct('spak'))
# print('goof => ' + correct('goof'))
# print('babyu => ' + correct('babyu'))
# print('spalling => ' + correct('spalling'))
# print("Hello =>"+ correct('Hello'))


EsQuery.py

# -*- coding: utf-8 -*-
#__author__="ZJL"from elasticsearch import Elasticsearch
import jieba
import jieba.analyse
import re
import enchant_py
import jsonclass ESQuery(object):def __init__(self):self.es = Elasticsearch("127.0.0.1:9200")def ES_Query(self,es_index,es_doc_type,query_key_list,strs,num,size_num):from_num = (num - 1) * size_numsize_num = num * size_numesstrs = " ".join(strs.get("key_list", ""))str_key = strs.get("key_str", "")re_nums = re.findall(r'[0-9]+', esstrs)re_nums_list = []if re_nums:for re_num in re_nums:re_nums_list.append({"match": {"age": re_num}})for query_key in query_key_list:re_nums_list.append({"match": {query_key: esstrs}})print(re_nums_list)body = {"query":{"bool":{"must": [],"must_not": [],"should": re_nums_list}},"from": from_num,"size": size_num,"sort": [],"aggs": {},# 关键字高亮"highlight": {"fields": {"school": {},"name":{}}}}a = self.es.search(index=es_index, doc_type=es_doc_type,body=body)aa = a["hits"]aa["key_str"] = str_keydata_json = json.dumps(aa)print(data_json)return (data_json)def Check_Keyword(self,key_str):# 词库file_name = "dict.txt"# 停用词 stop_words.txtstop_file_name = "stop_words.txt"# 加载词库jieba.load_userdict(file_name)# 加载停用词jieba.analyse.set_stop_words(stop_file_name)key_str_copy = key_str# 正则找出所有英文单词result_list = re.findall(r'[a-zA-Z]+', key_str_copy)# key_str_list = list(jieba.cut(key_str.strip()))# print(key_str_list)# 单词量小于3(百度超过两个也不纠错),将单词纠错,将原词与纠错后的词添加到字典corr_dict = {}if len(result_list)<3 and len(result_list)>0:for restr in result_list:strd = enchant_py.correct(restr)if restr!=strd:corr_dict[restr] = strd# 将纠错后的词替换原来的单词for corr in corr_dict:key_str_copy = key_str_copy.replace(corr,corr_dict.get(corr,""))# jieba的tf-idf算法,提取关键词tagstr = jieba.analyse.extract_tags(key_str_copy, topK=20, withWeight=False, allowPOS=())# 考虑到英文短句超不多在这个范围,且不太会有停用词,这样中英文结合后也能去掉中文的停用词elif len(result_list)<3 and len(result_list)>5:tagstr = jieba.analyse.extract_tags(key_str_copy, topK=20, withWeight=False, allowPOS=())# 英文单词过多就直接原样输出else:# 分词key_str_list = list(jieba.cut(key_str_copy))# 如果全英文中出现特殊符号就去掉stop_key = [" ","(",")",".",",","\'","\"","*","+","-","\\","/","`","~","@","#","$","%","^","&",'[',']',"{","}",";","?","!","\t","\n",":"]for key in stop_key:if key in key_str_list:key_str_list.remove(key)tagstr = key_str_list# 如果单词没有纠错就不显示if corr_dict:data_str = key_strelse:data_str = ""data = {"key_list":tagstr,"key_str":data_str}print(data)return data

flaskrun.py

# -*-coding:utf-8 -*-__author__ = "ZJL"from flask import Flask
from flask import request
from EsQuery import ESQuery
from werkzeug.contrib.fixers import ProxyFixapp = Flask(__name__)"""
@api {get} / 首页
@apiName index
@apiGroup indexx
"""
@app.route("/")
def index():return "hello world""""
@api {get} /query 查询
@apiName 查询
@apiGroup 查询xx 
@apiParam {string} strs 关键字
@apiParam {string} num 页码.
@apiParam {string} size_num 每页数量
"""
@app.route('/query', methods=['GET'])
def es_query():if request.method == 'GET' and request.args['strs'] and request.args['num'] and request.args['size_num']:num = int(request.args['num'])size_num = int(request.args['size_num'])strs = request.args['strs']eq = ESQuery()key_str_dict = eq.Check_Keyword(strs)es_index = ["test99911"]es_type = []es_query_list = ["title","body"]data_json = eq.ES_Query(es_index, es_type, es_query_list,key_str_dict, num, size_num)return data_jsonelse:return "no"app.wsgi_app = ProxyFix(app.wsgi_app)
if __name__ == "__main__":app.run(host="0.0.0.0",port=5123) # ,debug=True,threaded=True# 分别通过3中方式获取参数:request.form, request.args,request.values# postForm= request.form# getArgs= request.args# postValues= request.values




dict.txt

相似度 5

stop_words.txt

的
了
和
是
就
都
而
及
與
著
或
一個
沒有
我們
你們
妳們
他們
她們
是否
与
着
一个
没有
我们
你们
他们
她们
它们

big.txt太长了不贴了






这篇关于自制搜索(elasticsearch安装,mongo-connector同步数据,python操作)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110787

相关文章

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

使用Java填充Word模板的操作指南

《使用Java填充Word模板的操作指南》本文介绍了Java填充Word模板的实现方法,包括文本、列表和复选框的填充,首先通过Word域功能设置模板变量,然后使用poi-tl、aspose-words... 目录前言一、设置word模板普通字段列表字段复选框二、代码1. 引入POM2. 模板放入项目3.代码

Python打包成exe常用的四种方法小结

《Python打包成exe常用的四种方法小结》本文主要介绍了Python打包成exe常用的四种方法,包括PyInstaller、cx_Freeze、Py2exe、Nuitka,文中通过示例代码介绍的非... 目录一.PyInstaller11.安装:2. PyInstaller常用参数下面是pyinstal