官方文档https://www.elastic.co/guide/en/elasticsearch/reference/5.0/suggester-context.html

  下面所有演示基于elasticsearch5.x和Python3.x

  最近项目使用elasticsearch的补全功能时,需要对于所有文章(article)的作者名字(author)的搜索做补全,文章的mapping大致如下

ARTICLE = {
'properties': {
'id': {
'type': 'integer',
'index': 'not_analyzed',
},
'author': {
'type': 'text',
},
'author_completion': {
'type': 'completion',
},
'removed': {
'type': 'boolean',
}
}
} MAPPINGS = {
'mappings': {
'article': ARTICLE,
}
}

  现在的需求是,针对于下架状态removed为True的不做补全提示。

  作为演示先插入部分数据,代码如下

  

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from elasticsearch.helpers import bulk
from elasticsearch import Elasticsearch ES_HOSTS = [{'host': 'localhost', 'port': 9200}, ] ES = Elasticsearch(hosts=ES_HOSTS) INDEX = 'test_article'
TYPE = 'article' ARTICLE = {
'properties': {
'id': {
'type': 'integer',
'index': 'not_analyzed',
},
'author': {
'type': 'text',
},
'author_completion': {
'type': 'completion',
},
'removed': {
'type': 'boolean',
}
}
} MAPPINGS = {
'mappings': {
'article': ARTICLE,
}
} def create_index():
"""
插入数据前创建对应的index
"""
ES.indices.delete(index=INDEX, ignore=404)
ES.indices.create(index=INDEX, body=MAPPINGS) def insert_data():
"""
添加测试数据
:return:
"""
test_datas = [
{
'id': 1,
'author': 'tom',
'author_completion': 'tom',
'removed': False
},
{
'id': 2,
'author': 'tom_cat',
'author_completion': 'tom_cat',
'removed': True
},
{
'id': 3,
'author': 'kitty',
'author_completion': 'kitty',
'removed': False
},
{
'id': 4,
'author': 'tomato',
'author_completion': 'tomato',
'removed': False
},
]
bulk_data = []
for data in test_datas:
action = {
'_index': INDEX,
'_type': TYPE,
'_id': data.get('id'),
'_source': data
}
bulk_data.append(action) success, failed = bulk(client=ES, actions=bulk_data, stats_only=True) print('success', success, 'failed', failed) if __name__ == '__main__':
create_index()
insert_data()

  成功插入4条测试数据,下面测试获取作者名称补全建议,代码如下

def get_suggestions(keywords):
body = {
# 'size': 0, # 这里是不返回相关搜索结果的字段,如author,id等,作为测试这里返回
'_source': 'suggest',
'suggest': {
'author_prefix_suggest': {
'prefix': keywords,
'completion': {
'field': 'author_completion',
'size': 10,
}
}
},
# 对于下架数据,我单纯的以为加上下面的筛选就行了
'query': {
'term': {
'removed': False
}
}
}
suggest_data = ES.search(index=INDEX, doc_type=TYPE, body=body)
return suggest_data if __name__ == '__main__':
# create_index()
# insert_data() suggestions = get_suggestions('t')
print(suggestions)
"""
suggestions = {
'took': 0,
'timed_out': False,
'_shards': {
'total': 5,
'successful': 5,
'skipped': 0,
'failed': 0
},
'hits': {
'total': 3,
'max_score': 0.6931472,
'hits': [
{'_index': 'test_article', '_type': 'article', '_id': '4', '_score': 0.6931472,
'_source': {}},
{'_index': 'test_article', '_type': 'article', '_id': '1', '_score': 0.2876821,
'_source': {}},
{'_index': 'test_article', '_type': 'article', '_id': '3', '_score': 0.2876821,
'_source': {}}]},
'suggest': {
'author_prefix_suggest': [{'text': 't', 'offset': 0, 'length': 1, 'options': [
{'text': 'tom', '_index': 'test_article', '_type': 'article', '_id': '1', '_score': 1.0,
'_source': {}},
{'text': 'tom_cat', '_index': 'test_article', '_type': 'article', '_id': '2', '_score': 1.0,
'_source': {}},
{'text': 'tomato', '_index': 'test_article', '_type': 'article', '_id': '4', '_score': 1.0,
'_source': {}}]}]
}
}
"""

  发现,removed为True的tom_cat赫然在列,明明加了

'query': {
'term': {
'removed': False
}
}

  却没有起作用,难道elasticsearch不支持这种需求!?怎么可能……

  查阅文档发现解决方法为https://www.elastic.co/guide/en/elasticsearch/reference/5.0/suggester-context.html

  找到问题所在,首先改造mapping,并重新录入测试数据如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from elasticsearch.helpers import bulk
from elasticsearch import Elasticsearch ES_HOSTS = [{'host': 'localhost', 'port': 9200}, ] ES = Elasticsearch(hosts=ES_HOSTS) INDEX = 'test_article'
TYPE = 'article' ARTICLE = {
'properties': {
'id': {
'type': 'integer',
'index': 'not_analyzed'
},
'author': {
'type': 'text',
},
'author_completion': {
'type': 'completion',
'contexts': [ # 这里是关键所在
{
'name': 'removed_tab',
'type': 'category',
'path': 'removed'
}
]
},
'removed': {
'type': 'boolean',
}
}
} MAPPINGS = {
'mappings': {
'article': ARTICLE,
}
} def create_index():
"""
插入数据前创建对应的index
"""
ES.indices.delete(index=INDEX, ignore=404)
ES.indices.create(index=INDEX, body=MAPPINGS) def insert_data():
"""
添加测试数据
:return:
"""
test_datas = [
{
'id': 1,
'author': 'tom',
'author_completion': 'tom',
'removed': False
},
{
'id': 2,
'author': 'tom_cat',
'author_completion': 'tom_cat',
'removed': True
},
{
'id': 3,
'author': 'kitty',
'author_completion': 'kitty',
'removed': False
},
{
'id': 4,
'author': 'tomato',
'author_completion': 'tomato',
'removed': False
},
]
bulk_data = []
for data in test_datas:
action = {
'_index': INDEX,
'_type': TYPE,
'_id': data.get('id'),
'_source': data
}
bulk_data.append(action) success, failed = bulk(client=ES, actions=bulk_data, stats_only=True) print('success', success, 'failed', failed) if __name__ == '__main__':
create_index()
insert_data()

  Duang!意想不到的问题出现了

elasticsearch.helpers.BulkIndexError: ('4 document(s) failed to index.', [{'index': {'_index': 'test_article', '_type': 'article', '_id': '1', 'status': 400, 'error': {'type': 'illegal_argument_exception', 'reason': 'Failed to parse context field [removed], only keyword and text fields are accepted'}, 'data': {'id': 1, 'author': 'tom', 'author_completion': 'tom', 'removed': False}}}, {'index': {'_index': 'test_article', '_type': 'article', '_id': '2', 'status': 400, 'error': {'type': 'illegal_argument_exception', 'reason': 'Failed to parse context field [removed], only keyword and text fields are accepted'}, 'data': {'id': 2, 'author': 'tom_cat', 'author_completion': 'tom_cat', 'removed': True}}}, {'index': {'_index': 'test_article', '_type': 'article', '_id': '3', 'status': 400, 'error': {'type': 'illegal_argument_exception', 'reason': 'Failed to parse context field [removed], only keyword and text fields are accepted'}, 'data': {'id': 3, 'author': 'kitty', 'author_completion': 'kitty', 'removed': False}}}, {'index': {'_index': 'test_article', '_type': 'article', '_id': '4', 'status': 400, 'error': {'type': 'illegal_argument_exception', 'reason': 'Failed to parse context field [removed], only keyword and text fields are accepted'}, 'data': {'id': 4, 'author': 'tomato', 'author_completion': 'tomato', 'removed': False}}}])

  意思是context只支持keyword和text类型,而上面removed类型为boolean,好吧,再改造mapping,将mapping的removed改为keyword类型……

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from elasticsearch.helpers import bulk
from elasticsearch import Elasticsearch ES_HOSTS = [{'host': 'localhost', 'port': 9200}, ] ES = Elasticsearch(hosts=ES_HOSTS) INDEX = 'test_article'
TYPE = 'article' ARTICLE = {
'properties': {
'id': {
'type': 'integer',
'index': 'not_analyzed'
},
'author': {
'type': 'text',
},
'author_completion': {
'type': 'completion',
'contexts': [ # 这里是关键所在
{
'name': 'removed_tab',
'type': 'category',
'path': 'removed'
}
]
},
'removed': {
'type': 'keyword',
}
}
} MAPPINGS = {
'mappings': {
'article': ARTICLE,
}
} def create_index():
"""
插入数据前创建对应的index
"""
ES.indices.delete(index=INDEX, ignore=404)
ES.indices.create(index=INDEX, body=MAPPINGS) def insert_data():
"""
添加测试数据
:return:
"""
test_datas = [
{
'id': 1,
'author': 'tom',
'author_completion': 'tom',
'removed': 'False'
},
{
'id': 2,
'author': 'tom_cat',
'author_completion': 'tom_cat',
'removed': 'True'
},
{
'id': 3,
'author': 'kitty',
'author_completion': 'kitty',
'removed': 'False'
},
{
'id': 4,
'author': 'tomato',
'author_completion': 'tomato',
'removed': 'False'
},
]
bulk_data = []
for data in test_datas:
action = {
'_index': INDEX,
'_type': TYPE,
'_id': data.get('id'),
'_source': data
}
bulk_data.append(action) success, failed = bulk(client=ES, actions=bulk_data, stats_only=True) print('success', success, 'failed', failed) if __name__ == '__main__':
create_index()
insert_data()

  mission success。看看表结构ok

接下来就是获取补全建议

def get_suggestions(keywords):
body = {
'size': 0,
'_source': 'suggest',
'suggest': {
'author_prefix_suggest': {
'prefix': keywords,
'completion': {
'field': 'author_completion',
'size': 10,
'contexts': {
'removed_tab': ['False', ] # 筛选removed为'False'的补全,contexts不能包含多个tab,如加上一个'state_tab':['1',]的话contexts将失效
}
}
}
},
}
suggest_data = ES.search(index=INDEX, doc_type=TYPE, body=body)
return suggest_data if __name__ == '__main__':
# create_index()
# insert_data()
suggestions = get_suggestions('t')
print(suggestions) """
suggestions = {
'took': 0,
'timed_out': False,
'_shards': {
'total': 5,
'successful': 5,
'skipped': 0, 'failed': 0
},
'hits': {
'total': 0,
'max_score': 0.0,
'hits': []
},
'suggest': {
'author_prefix_suggest': [
{'text': 't', 'offset': 0, 'length': 1, 'options': [
{'text': 'tom', '_index': 'test_article', '_type': 'article', '_id': '1', '_score': 1.0,
'_source': {},
'contexts': {'removed_tab': ['False']}},
{'text': 'tomato', '_index': 'test_article', '_type': 'article', '_id': '4', '_score': 1.0,
'_source': {},
'contexts': {'removed_tab': ['False']}}]}]}}
"""

  发现,removed为'True'的tom_cat被筛选掉了,大功告成!

elasticsearch补全功能之只补全筛选后的部分数据context suggester的更多相关文章

  1. CentOS 5 全功能WWW服务器搭建全教程 V3.0

    http://hx100.blog.51cto.com/44326/339949/ 一.基本系统安装1.下载CentOS 5我是下载的DVD版本,大家也可以下载服务器CD安装版本,其实都差不多.大家可 ...

  2. Eclipse自动补全功能轻松设置 || 不需要修改编辑任何文件

    本文介绍如何设置Eclipse代码自动补全功能.轻松实现输入任意字母均可出现代码补全提示框.   Eclipse代码自动补全功能默认只包括 点"."  ,即只有输入”." ...

  3. Eclipse使用技巧 - 2. Eclipse自动补全功能轻松设置

    本文介绍如何设置Eclipse代码自动补全功能.轻松实现输入任意字母均可出现代码补全提示框. Eclipse代码自动补全功能默认只包括 点”.” ,即只有输入”.”后才出现自动补全的提示框.想要自动补 ...

  4. 转:Eclipse自动补全功能轻松设置

    Eclipse自动补全功能轻松设置 || 不需要修改编辑任何文件 2012-03-08 21:29:02|  分类: Java |  标签:eclipse  自动补全  设置  |举报|字号 订阅   ...

  5. vim基础学习之自动补全功能

    本章我们学习自动补全功能1.自动补全优先从当前的编辑区获得补全列表例如:我们写下如下内容 aaaaa aabbb aaab 当我们再次输入aa,然后我们按下Tab的时候,会弹出一个包含 aaaaa a ...

  6. 第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能

    第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—用Django实现搜索的自动补全功能 elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.e ...

  7. 四十七 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能

    elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.elastic.co/guide/en/elasticsearch/reference/current/se ...

  8. java整合Elasticsearch,实现crud以及高级查询的分页,范围,排序功能,泰文分词器的使用,分组,最大,最小,平均值,以及自动补全功能

    //为index创建mapping,index相当于mysql的数据库,数据库里的表也要给各个字段创建类型,所以index也要给字段事先设置好类型: 使用postMan或者其他工具创建:(此处我使用p ...

  9. linux命令补全 忘记命令只记得开头

    linux的shell不仅提供上下箭头来翻阅历史使用过的命令,还提供命令补全功能. 例如,你想创建一个文件夹,只记得是m开头的命令,此时可以: ①输入m ②按键盘上的Tab键两次 (有可能还出现这句话 ...

随机推荐

  1. Spring Boot 1.5.x 基础学习示例

    一.为啥要学Spring Boot? 今年从原来.Net Team“被”转到了Java Team开始了微服务开发的工作,接触了Spring Boot这个新瓶装旧酒的技术,也初步了解了微服务架构.Spr ...

  2. Android-PickerView【仿iOS的PickerView控件,并封装了时间选择和选项选择这两种选择器】使用

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本文主要演示Android-PickerView的选项选择器.时间选择器的简单运用.由于每一个版本略有不用,所以实际使用方式以git ...

  3. 小议 localStorage

    前言 什么是 localStorage? 在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条co ...

  4. logistic逻辑回归公式推导及R语言实现

    Logistic逻辑回归 Logistic逻辑回归模型 线性回归模型简单,对于一些线性可分的场景还是简单易用的.Logistic逻辑回归也可以看成线性回归的变种,虽然名字带回归二字但实际上他主要用来二 ...

  5. Docker进阶之四:镜像管理

      一.什么是镜像? 简单说,Docker镜像是一个不包含Linux内核而又精简的Linux操作系统. 二.镜像从哪里来? Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容 ...

  6. sublime text3插件解决输入法不跟随的问题

    快捷键ctrl + shift +p 输入  install package 回车,调出插件搜索器, 在搜索栏中输入 IMESupport 回车安装插件. 即可解决问题.

  7. 常见js报错

    1Uncaught TypeError: Cannot read property 'length' of null Uncaught TypeError: Cannot read property ...

  8. C# 默认访问权限

    声明类.方法.字段.属性时不加访问权限修饰符时的访问权限是什么呢?1. 声明命名空间.类,前面不加限制访问修饰符时,默认访问权限为internal——访问仅限于当前程序集. 2. 声明类成员(域.属性 ...

  9. HotSpot 虚拟机垃圾回收算法实现

    作为使用范围最广的虚拟机之一HotSpot,必须对垃圾回收算法的执行效率有严格的考量,只有这样才能保证虚拟机高效运行 枚举根节点 从可达性分析中从 GC Roots 节点找引用链这个操作为例,可以作为 ...

  10. MySQL数据连表查询思路

    我们在网站开发中,涉及MySQL数据库查询时,常常需要将两个表或多个表联合起来进行查询数据,这就用到了MySQL中的JOIN函数. JOIN函数有三种,分别是: LEFT JOIN  左连接查询: 查 ...