一、配置
python == 3.6/3.8
pip install elasticsearch==7.8.0
二、连接es
from elasticsearch import Elasticsearch
es = Elasticsearch('ip:port')
三、查看索引是否存在,删除索引
http://ip:port/_cat/indices?v&pretty
http://ip:port/index_name/_settings?pretty
三、创建索引与映射
def create_index(es, index_name):
settings = {
'settings':
{
"number_of_shards": 5,
"number_of_replicas": 0,
"max_result_window": 10000000,
"track_total_hits": True,
}
}
if es.indices.exists(index_name):
print(u"%s 已存在" % index_name)
else:
es.indices.create(index=index_name, body=settings)
print(index_name + "索引创建成功")
res = es.indices.create(index='index_name', ignore=400)
print(res)
"""
分词器主要有两种情况会被使用:
第一种是插入文档时,将text类型的字段做分词然后插入倒排索引,对应analyzer
第二种就是在查询时,先对要查询的text类型的输入做分词,再去倒排索引搜索,对应search_analyzer
如果想要让 索引 和 查询 时使用不同的分词器,ElasticSearch也是能支持的,只需要在字段上加上search_analyzer参数
在索引时,只会去看字段有没有定义analyzer,有定义的话就用定义的,没定义就用ES预设的
在查询时,会先去看字段有没有定义search_analyzer,如果没有定义,就去看有没有analyzer,再没有定义,才会去使用ES预设的
"""
mapping = {
'properties': {
'title': {
'type': 'string',
'analyzer': 'jieba',
},
'content': {
'include_in_all': True,
'analyzer': 'jieba',
'index': "analyzed",
'boost': 2,
'term_vector': 'with_positions_offsets',
'type': 'string',
},
}
}
result = es.indices.put_mapping(index='index_name', doc_type='doc', body=mapping)
print(result)
四、查询索引
1、match_all查询所有
body = {
"query": {
"match_all": {},
},
"size": 50,
}
result = es.search(index='index_name', doc_type='doc_type', body=body)
2、分词相关查询
关键词 |
keyword类型 |
text类型 |
是否支持分词 |
term |
完全匹配 |
查询条件中关键词不会被分词,它必须整个关键词和document中的某个分词匹配,才能搜索到,多个分词时必须连续,顺序不能颠倒。 |
是 |
match |
完全匹配 |
match分词结果和text的分词结果有相同的即可 |
否 |
match_phrase |
完全匹配 |
match_phrase的分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。 |
是 |
query_string |
完全匹配 |
query_string中和match_string基本一样,区别是它不考虑顺序 |
是 |
body = {
"query": {
"term": {
"content": "汽车保养"
"from": 1,
"size": 30,
}
}
}
body = {
"query": {
"match": {"title": "宝马法拉利兰博基尼"},
},
}
body = {
"query": {
"match_phrase": {"title": "宝马法拉利兰博基尼"},
},
}
body = {
"query": {
"query_string": {
"fields": ["title", "content"],
"query": text,
}
}
}
3、bool组合查询
"""
bool能将多个简单查询组合起来。
使用 must、should、must_not、filter 选项来表示简单查询之间的逻辑,每个选项都可以出现 0 次到多次。
must:文档必须匹配,该选项下的查询条件,相当于逻辑运算的 AND,且参与文档相关度的评分。
should:文档可以匹配 should 选项下的查询条件也可以不匹配,相当于逻辑运算的 OR,且参与文档相关度的评分。
must_not:与 must 相反,匹配该选项下的查询条件的文档不会被返回;需要注意的是,must_not 语句不会影响评分,它的作用只是将不相关的文档排除。
filter:和 must 一样,匹配 filter 选项下的查询条件的文档才会被返回,但是 filter 不评分,只起到过滤功能,与 must_not 相反。
"""
{
"query": {
"bool": {
"filter": {
"term": { "status": 1 }
},
"must_not": {
"range": { "price": { "gte": 70 } }
},
"must": {
"match": { "title": "java" }
},
"should": [
{
"match": { "description": "虚拟机" }
},
{
"match": { "content": "计算公式" }
}
]
}
}
}
"""
控制精度
must 语句必须匹配,但有多少 should 语句应该匹配呢?默认情况下,没有 should 语句是必须匹配的,只有一个例外,那就是当没有 must 语句的时候,至少有一个 should 语句必须匹配。
此外可以通过 minimum_should_match 参数控制需要匹配的 should 语句的数
计算规则
bool 查询采用“匹配越多越好(more_matches_is_better)”的机制,因此满足 must 和 should 子句的文档将会合并起来计算分值。
在 filter 子句查询中,分值将会都返回 0。
must_not 子句并不影响得分,它们存在的意义是排除已经被包含的文档。
如上所述,bool 查询的计算得分主要是 must 和 should 子句,它们的计算规则是,把所有符合 must 和 should 的子句得分加起来,然后乘以匹配子句的数量,再除以子句的总数。
"""
def diffWordOrQuery(field, size, texts, boolnext=[], boolnext2=[]):
"""
作用: 构建bool查询query查询体
field:str.要检索的字段
size:int.单次检索要返回的数量
texts:list.对检索文本进行分词后的词列表
boolnext:list.bool的下一级key,对每个texts要采取的匹配策略
boolnext2:list.bool的下下一级key,对应match、term、range
"""
if len(boolnext) < len(texts):
for i in range(len(texts) - len(boolnext)):
boolnext.append("should")
if len(boolnext2) < len(texts):
for i in range(len(texts) - len(boolnext2)):
boolnext2.append("should")
body = {
"query": {
"bool": {
},
},
"size": size,
}
for i, text in enumerate(texts):
if text == " ":
continue
method = boolnext[i]
method2 = boolnext2[i]
sonlst = body["query"]["bool"].get(method, None)
if not sonlst:
body["query"]["bool"][method] = {method2: {field: text}}
else:
son = body["query"]["bool"][method]
if type(son) == dict:
for key1, value1 in son.items():
for key2, value2 in value1.items():
body["query"]["bool"][method] = [{key1: {key2: value2}}, {method2: {field: text}}]
else:
son.append({method2: {field: text}})
return body
texts = ["阅读", "语文", "英语", "数学", "政治"]
boolnext = ["must", "must_not", "must"]
boolnext2 = ["term", "match"]
body = diffWordOrQuery("title", 50, texts, boolnext, boolnext2)
print(body)
出处:https://www.cnblogs.com/moyezq/p/17022844.html