头条全文检索实现
头条全文检索实现
elasticsearch python客户端使用
https://elasticsearch-py.readthedocs.io/en/master/>
pip install elasticsearch
对于elasticsearch 5.x 版本 需要按以下方式导入
from elasticsearch5 import Elasticsearch # elasticsearch集群服务器的地址 ES = [ '127.0.0.1:9200' ] # 创建elasticsearch客户端 es = Elasticsearch( ES, # 启动前嗅探es集群服务器 sniff_on_start=True, # es集群服务器结点连接异常时是否刷新es结点信息 sniff_on_connection_fail=True, # 每60秒刷新结点信息 sniffer_timeout=60 )
sniff(mean:嗅探)
搜索使用方式
query = { 'query': { 'bool': { 'must': [ {'match': {'_all': 'python web'}} ], 'filter': [ {'term': {'status': 2}} ] } } }
ret = es.search(index='articles', doc_type='article', body=query)
头条项目搜索接口视图实现
在toutiao-backend/toutiao/resources/search目录中新建search.py
from flask_restful import Resource from flask_restful.reqparse import RequestParser from flask_restful import inputs from flask import g, current_app from redis.exceptions import RedisError from . import constants from cache import article as cache_article from cache import user as cache_user from models.user import Search from models import db class SearchResource(Resource): """ 搜索结果 """ def get(self): """ 获取搜索结果 """ qs_parser = RequestParser() qs_parser.add_argument('q', type=inputs.regex(r'^.{1,50}$'), required=True, location='args') qs_parser.add_argument('page', type=inputs.positive, required=False, location='args') qs_parser.add_argument('per_page', type=inputs.int_range(constants.DEFAULT_SEARCH_PER_PAGE_MIN, constants.DEFAULT_SEARCH_PER_PAGE_MAX, 'per_page'), required=False, location='args') args = qs_parser.parse_args() q = args.q page = 1 if args.page is None else args.page per_page = args.per_page if args.per_page else constants.DEFAULT_SEARCH_PER_PAGE_MIN # Search from Elasticsearch query = { 'from': (page-1)*per_page, 'size': per_page, '_source': False, 'query': { 'bool': { 'must': [ {'match': {'_all': q}} ], 'filter': [ {'term': {'status': 2}} ] } } } ret = current_app.es.search(index='articles', doc_type='article', body=query) total_count = ret['hits']['total'] results = [] hits = ret['hits']['hits'] for result in hits: article_id = int(result['_id']) article = cache_article.ArticleInfoCache(article_id).get() if article: results.append(article) # Record user search history if g.user_id and page == 1: try: cache_user.UserSearchingHistoryStorage(g.user_id).save(q) except RedisError as e: current_app.logger.error(e) return {'total_count': total_count, 'page': page, 'per_page': per_page, 'results': results}
在toutiao-backend/toutiao/resources/search目录中新建constants.py
# 搜索结果分页默认每页数量 下限 DEFAULT_SEARCH_PER_PAGE_MIN = 10 # 搜索结果页默认每页数量 上限 DEFAULT_SEARCH_PER_PAGE_MAX = 50
添加ES新文章索引数据
在自媒体平台发布文章接口中,除了保存文章外,还要向es库中添加新文章的索引
doc = { 'article_id': article.id, 'user_id': article.user_id, 'title': article.title, 'content': article.content.content, 'status': article.status, 'create_time': article.ctime }
current_app.es.index(index='articles', doc_type='article', body=doc, id=article.id)
壬戌之秋,七月既望,苏子与客泛舟游于赤壁之下。清风徐来,水波不兴。举酒属客,诵明月之诗,歌窈窕之章。少焉,月出于东山之上,徘徊于斗牛之间。白露横江,水光接天。纵一苇之所如,凌万顷之茫然。浩浩乎如冯虚御风,而不知其所止;飘飘乎如遗世独立,羽化而登仙。
于是饮酒乐甚,扣舷而歌之。歌曰:“桂棹兮兰桨,击空明兮溯流光。渺渺兮予怀,望美人兮天一方。”客有吹洞箫者,倚歌而和之。其声呜呜然,如怨如慕,如泣如诉,余音袅袅,不绝如缕。舞幽壑之潜蛟,泣孤舟之嫠妇。
苏子愀然,正襟危坐而问客曰:“何为其然也?”客曰:“月明星稀,乌鹊南飞,此非曹孟德之诗乎?西望夏口,东望武昌,山川相缪,郁乎苍苍,此非孟德之困于周郎者乎?方其破荆州,下江陵,顺流而东也,舳舻千里,旌旗蔽空,酾酒临江,横槊赋诗,固一世之雄也,而今安在哉?况吾与子渔樵于江渚之上,侣鱼虾而友麋鹿,驾一叶之扁舟,举匏樽以相属。寄蜉蝣于天地,渺沧海之一粟。哀吾生之须臾,羡长江之无穷。挟飞仙以遨游,抱明月而长终。知不可乎骤得,托遗响于悲风。”
苏子曰:“客亦知夫水与月乎?逝者如斯,而未尝往也;盈虚者如彼,而卒莫消长也。盖将自其变者而观之,则天地曾不能以一瞬;自其不变者而观之,则物与我皆无尽也,而又何羡乎!且夫天地之间,物各有主,苟非吾之所有,虽一毫而莫取。惟江上之清风,与山间之明月,耳得之而为声,目遇之而成色,取之无禁,用之不竭,是造物者之无尽藏也,而吾与子之所共适。”
客喜而笑,洗盏更酌。肴核既尽,杯盘狼籍。相与枕藉乎舟中,不知东方之既白。

浙公网安备 33010602011771号