ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
基于HTTP协议,以JSON为数据格式的RESTful API
Get 'http://localhost:3000/web/people' { "query": { } }以上语句查询了web库people表的所有数据
这是查询magazine这个表的mapping,如果想要查询整个数据库的mapping,去掉表名即可 说一下常用的几个类型
text 和 keyword 都是string类型,区别在于keyword在存储的时候不会进行分词,用于精确精确检索。long 和 integer 都是number类型date 是时间类型
filter查询,用于过滤,不会参与到评分的计算中,并且会进行缓存,所以filter查询更快
使用 查询(query)语句来进行 全文 搜索或者其它任何需要影响 相关性得分 的搜索。除此以外的情况都使用过滤(filters)。
等价sql:
SELECT people_id, title FROM people WHERE type = 12 ORDER BY view DESC LIMIT 10 OFFSET 0当我们想有更多的过滤条件时,就可以在filter中添加更多的查询条件(子查询)
term 是一个值的精确查询,这些精确值可能是数字、时间、布尔或者那些 not_analyzed(例如keyword类型) 的字符串terms 是多个值的精确查询range是范围查询 gt: > 大于(greater than)lt: < 小于(less than)gte: >= 大于或等于(greater than or equal to)lte: <= 小于或等于(less than or equal to)Get 'http://localhost:3000/web/people' { "query": { "bool": { "filter": [ { "term": { "type": 11 } }, { "range": { "times": { "gte": 5, "lte": 10 } } }, { "terms": { "car_type": [ 1, 2, 4 ] } } ] } } }我们往往会需要更复杂的查询,就需要用到bool组合查询支持下面四个分类数:must 文档 必须 匹配这些条件才能被包含进来。must_not 文档 必须不 匹配这些条件才能被包含进来。should 如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。filter 必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。
{ "query":{ "bool": { "must": { "match": { "title": "学习Elasticsearch" }}, "must_not": { "match": { "comment": "写的不好" }}, "should": [ { "match": { "comment": "写的很棒" }} ], "filter": { "bool": { "must": [ { "range": { "date": { "gte": "2018-01-01" }}} ], "must_not": [ { "term": { "category": "education" }} ] } } } } }这是一个很好的简单易懂的例子: 它查询了时间大于等于2018-01-01、分类不是education的、并且title中含有"学习Elasticsearch"、comment中一定不含有"写的不好"的文章 ,看起来其中的should好像并没有什么用呢,其实不是,should条件参加相关度的评分,让更符合目标的结果(commen中含有"写的很棒")排在前面。 这其中有个小点要注意下:如果没有 must 语句,那么至少需要能够匹配其中的一条 should 语句。但,如果存在至少一条 must 语句,则对 should 语句的匹配没有要求。 刚才对这个查询的描述其实并不是很准确,我们需要了解一下这个match查询 如果你在一个全文字段上使用 match 查询,在执行查询前,它将用正确的分析器去分析查询字符串,这里涉及到一个新的概念分析器
一个分析器(analyzer)包含了一个或多个字符过滤器(char_filter)、一个分词器(tokenizer)、一个或多个词单元过滤器(filter) 重点说一下分词器es默认的分析器是standard,以后关于分析器还需要详细讲一下,这里标准的分析器会把字符串分割成单独的字词,如果检索的是英文的话,倒是没有什么问题,如果是中文的话,会把检索字符串的每一个汉字分成一个词,如下:
Post http://localhost:3000/web/_analyze?analyzer=standard { "tokens": [ { "token": "学", "start_offset": 0, "end_offset": 1, "type": "", "position": 0 }, { "token": "习", "start_offset": 1, "end_offset": 2, "type": "", "position": 1 }, { "token": "elasticsearch", "start_offset": 2, "end_offset": 15, "type": "", "position": 2 } ] } { "match": { "title": "学习Elasticsearch" }所以这个代表是在title中任意包含“学”、“习”、‘elasticsearch’中任意一个的都被检索了出来,所以需要match_phrase才能满足我们的需求,代表的是整个短语的匹配,要求 “学”、“习”、‘elasticsearch’三个词都必须出现,“习”的position比“学”大1,‘elasticsearch’比“习”的position大2,必须同时满足这3个条件。所以把上面的match换成match_phrase才是符合刚才的释义
结合使用:以上三个因素——词频(term frequency)、逆向文档频率(inverse document frequency)和字段长度归一值(field-length norm)——是在索引时计算并存储的。 最后将它们结合在一起计算单个词在特定文档中的 权重
ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。
该分析器是以","作为分隔符进行分词,【"standard","stop","trim"】这个三个作为过滤器
现在关键词字段内容格式如下,以英文逗号分开的,多个词语帆船,美女,红酒,大海,海螺,腰带期望检索出来和关键最相近的数据,设置如下的mapping,禁用了词频统计和长度归一值的计算
{ "keywords":{ "type":"text", "norms":false, "index_options":"docs", "analyzer":"keywordAnalyzer" } }采用如下检索
{ "query":{ "match":{ "keywords":{ "query":"帆船,美女,红酒,大海,海螺,腰带" } } } }我想要两个词都出现的是排在前面
{ "query": { "dis_max": { "queries": [ { "match": { "title": "Quick pets" }}, { "match": { "body": "Quick pets" }} ], "tie_breaker": 0.3 } } }我们回想一下,如果是英文这样是不是就OK了?那么中文呢? 和上面不相干,说另外一个东西,看下面
{ "query": { "dis_max": { "queries": [ { "match": { "title": "Quick pets" }}, { "match": { "body": "Quick pets" }} ] } } } ------------------------ { "multi_match": { "query": "Quick pets", "type": "best_fields", "fields": [ "title", "body" ] } }上面这个查询两个相等 但是上面的和下面的却完全不一样
{ "query":{ "bool":{ "should":[ { "match": { "title": "Quick pets" }}, { "match": { "body": "Quick pets" }} ] } } }回到刚才的问题 如果是英文刚才那个查询dis_max(multi_match)一定程度是ok的,但是中文却是不行的,为啥?因为match,虽然可以是100%匹配,但是他并没有像match_phrase字和字之间紧紧相连。所以只能拿出最终的神奇了query_string
{ "query":{ "bool":{ "should":[ { "query_string":{ "fields":[ "article_content" ], "analyzer":"ik_smart", "query":"迪奥 香水", "auto_generate_phrase_queries":true, "default_operator":"OR", "use_dis_max":true, "boost":1 } } ] } } }这个查询代表了用ik_smart分析器对迪奥 香水进行分词(mapping是ik_max_word),然后对article_content字段进行检索,要求迪奥和香水这个两个词必须出现一个或者出现两个,采用"use_dis_max":true使同时出现两个词的结果排在前面。
添加 "profile": true这个参数,可以相对清楚看出es是按照什么逻辑来检索的
{ "query": { "match": { "relevant_keywords": { "query": "米歇尔,美国,奥巴马,人物,女儿,总统,家庭" } } }, "size": 7, "from": 0, "_source": [ "article_id", "title", "relevant_keywords", "belong_program" ], "profile": true }转载于:https://www.cnblogs.com/mapleChain/p/11527895.html