Elasticsearch摘要

2 篇文章 0 订阅
2 篇文章 0 订阅

centos安装elasticsearch

  1. 导入密钥
rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch

2.增加资源配置库

在/etc/yum.repos.d目录下,增加yum资源库
[elasticsearch-2.x]
name=Elasticsearch repository for 2.x packages
baseurl=https://packages.elastic.co/elasticsearch/2.x/centos
gpgcheck=1
gpgkey=https://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1

3.安装

yum install elasticsearch

安装目录为:/usr/share/elasticsearch
4.配置开机自启动

chkconfig --add elasticsearch

安装中文分词IK插件

  1. 下载源代码
 git clone https://github.com/medcl/elasticsearch-analysis-ik.git

2.打包

mvn package
  1. 复制插件
    把打包目录target/release下的elasticsearch-analysis-ik-1.9.5.zip复制到 elasticsearch安装目录下面。 如: /usr/share/elasticsearch/plugins/ik
    4.配置
    plugins/ik/config/IKAnalyzer.cfg.xml
    可以直接配置词典和自定义词典

修改默认分词器

修改elasticsearch.yml配置文件,增加
#默认分词器,索引
index.analysis.analyzer.default.type: ik

#默认分词器,查询
index.analysis.analyzer.default_search.type: ik

使用步骤

  1. 创建索引
curl -XPUT http://localhost:9200/index
  1. 创建索引时指定文档的索引
curl -XPUT http://192.168.2.10:9200/traffic?pretty -d '
{
    "mappings": {
        "robot": {
            "properties": {
                "question": {
                    "include_in_all": true, 
                    "analyzer": "ik_syno", 
                    "term_vector": "with_positions_offsets", 
                    "boost": 8, 
                    "store": true, 
                    "type": "string"
                }
            }
        }
    }
}
'
表示traffic引用、robot类型的,question字段使用ik_syno分析器

安装验证

查看启动结果

curl -XGET http://127.0.0.1:9200/?pretty

日志

/var/log/elasticsearch/elasticsearch.log

映射mapping

定义了一个文档怎么被映射到搜索引擎,例如哪些引擎是可以被搜索的,以及他们怎么样被分词。
显示映射是定义在index/type层次上的。默认情况下不需要定义显示映射的,因为ES会默认帮我们创建,但是我们也可以改写ES创建的默认mapping。

document字段映射类型分为analyzed、not_analyzed、no

  • analyzed
    字段被分析、分词、索引,可以被检索。
  • not_analyzed
    字段不被分析、但是可以精确检索
  • no
    字段不被分析、索引,不能检索。

    分析器

    分析器包含三个功能,即字符过滤器、分词器、标记过滤。

    • 字符过滤器
      在标记前处理字符串,如去除HTML标记,或者转换&为and.
    • 分词器
      标记独立的词。如一个简单的分词器(tokenizer)可以根据空格或者逗号将单词分开。

    • 标记过滤
      每个词通过所有标记过滤器,可以修改词,去掉词,或者增加词(如同义词)

查看分词结果

查看默认分词结果

curl -XGET 'http://192.168.2.10:9200/traffic/_analyze?field=brand_name&pretty' -d '童装童鞋’

查看指定分词器分词结果

curl -XGET 'http://192.168.2.10:9200/traffic/_analyze?tokenizer=ik&field=brand_name&pretty' -d '童装童鞋'

curl -XGET 'http://192.168.2.10:9200/traffic/_analyze?tokenizer=standard&field=brand_name&pretty' -d '童装童鞋'

配置同义词

修改elasticsearch.yml,增加

index:
  analysis:
    analyzer:
      ik_syno:
        type: custom
        tokenizer: ik_max_word
        filter: [my_synonym_filter]
      ik_syno_smart:
        type: custom
        tokenizer: ik_smart
        filter: [my_synonym_filter]
    filter:
      my_synonym_filter:
        type: synonym
        synonyms_path: analysis/synonym.txt

在elasticsearch.yml同目录下的analysis子目录下,建立synonym.txt文件,格式为UTF-8。
格式为:

驾驶证,驾照
格式说明:
表示 出现a或者b,则相互分词.
a,b => c
a,b,c
第一种在分词的时候,a,b都会解析成为c,然后把c存入索引中
第二种在分词的时候,有a的地方,都会解析成a,b,c,把a,b,c存入索引中
第一种方法相比之下有个主词,比较省索引。

常见接口

  1. 创建索引
curl -XPUT http://ip:port/traffic?pretty -d '
{
    "mappings": {
        "robot": {
            "properties": {
                "question": {
                    "include_in_all": true, 
                    "analyzer": "ik_syno", 
                    "term_vector": "with_positions_offsets", 
                    "boost": 8, 
                    "store": true, 
                    "type": "string"
                }
            }
        }
    }
}
'
  1. 增加文档
curl -XPUT http://ip:port/traffic/robot/1 -d '
{
    "question": "对酒驾行为如何记分",
    "answer":"酒驾行为属于严重违法行为。公安部123号令作出了对饮酒后驾驶机动车的记12分的规定。饮酒后驾驶营运机动车、醉酒后驾驶营运或非营运机动车,吊销驾驶证。",
    "type":"酒驾"
}'
  1. 查询
查询所有的类型下的文档
curl -XGET 'http://ip:port/traffic/_search?pretty'
查询特定类型下的文档
curl -XGET 'http://ip:port/traffic/robot/_search?pretty'
查询特定类型下的文档
curl -XGET 'http://ip:port/traffic/robot/_search?pretty' -d '{
  "query" : {
    "query_string" : {
      "query" : "记分周期",
      "fields" : [ "question" ]
    }
  }
}'
  1. 删除文档
curl -XDELETE http://ip:port/traffic/robot/1
  1. 查看相关性的分析
curl -XGET http://ip:port/traffic/robot/_search?explain -d ' 
{
  "query": {
    "term": {
      "question": "闯红灯"
    }
  }
}'

6.查询在不同字段中的权重

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": {
              "query": "quick brown fox",
              "boost": 2 #1
            }
          }
        },
        {
          "match": { #2
            "content": "quick brown fox"
          }
        }
      ]
    }
  }
}
  • title 查询语句的重要性是 content 的2倍,因为它的权重提升值为2。
  • 一个没有设置权重提升的查询语句的值为1。

术语

  • 字段映射mapping中not_analyzed表示该字段不进行分析,作为精确值处理

  • term过滤器
    包含,只要出现即可,不参与记分

  • 基于term术语的查询
    只对反向索引的术语进行精确匹配

  • 基于全文的查询(Full-text queries)
    如match或query_string这样的高层次查询,它知道一个字段的映射:
  • 如果用来查询时间或者整数(integer),会讲查询字符串分别当做时间或者整数
  • 如果查询一个准确的(未分析过的not_analyzed)字符串字段,它会整个查询字符串当做一个术语
  • 如果查询一个全文字段(分析过的analyzed),它会讲查询字符串传入到一个合适的分析器,然后生成一个供查询的术语列表。
    一旦查询组成了一个术语列表,它会将每个术语逐一执行低层次的查询,然后将结果合并,为每个文档生成一个最终的相关性分数。
    -dis_max
    dis_max分离最大化查询(Disjunction Max Query)。分离的意思是或(or),这与把结合(conjunction)理解成(and)对应。分离最大化查询是指,将任何与任一查询匹配的文档作为结果返回,但是只将最佳匹配的分数作为查询的结果分数。
当想要准确查询一个未分析过的(not_analyzed)的字段之前,需要考虑是需要查询还是过滤。
-tie_break
使用tie_break参数将其它匹配语句的分数也考虑其中:

{
“query”: {
“dis_max”: {
“queries”: [
{ “match”: { “title”: “Quick pets” }},
{ “match”: { “body”: “Quick pets” }}
],
“tie_breaker”: 0.3
}
}
}

tie_breaker参数提供了一种处于dis_max和bool中间状态的查询,它分数计算的方式如下:
1.获得最佳匹配(best-matching)语句的分数 *_score*
2.将其他匹配语句的得分和tie_breaker向乘
3.讲以上分数求和并规范化(normalize)

注意:
tie_breaker 可以是 0 到 1 之间的浮点数,其中,如果数值为0,即代表使用dis_max最佳匹配语句的普通逻辑,如果数值为1,即表示所有匹配语句同等重要。最佳的准确值需要根据数据与查询进行调试得出,但是合理的值通常与零接近(处于 0.1 - 0.4 之间),这样的合理值不会改变 dis_max 使用最佳匹配的本质。

-词频(term frequencies)
默认使用的相似度算法是TF/IDF
 词频是指,一个词在单个文档中的某个字段出现的频率越高,这个文档的相关度越高
-逆向文件频率(Inverse document frequency)
 一个词在所有文档索引中出现的频率越高,这个词的相关度越低。

分析过程

  • 单个词查询
    释使用 match 在全文字段中使用单个词进行查找:
GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": "QUICK!"
        }
    }
}

ElasticSearch执行上面这个 match 查询的步骤是:

检查字段类型(Check the field type)

标题 title 字段是一个全文(analyzed) string 类型的字段,这意味着查询字符串本身也需要被分析(analyzed)。

分析查询字符串(Analyze the query string)

将查询的字符串 QUICK! 传入标准的分析器中(standard analyzer),输出的结果是 quick。因为对于单个术语,match 查询处理的是低层次的术语查询。

查找匹配文档(Find matching docs)

term 查询在反向索引中查找 quick 然后获取一组包含有术语的文档,在这个例子中为文档:1,2和3。

为每个文档计算分数(Score each doc)

term 查询为每个文档计算相关度分数,将术语频率(term frequency),即quick词在相关文档title中出现的频率,和反向文档频率(inverse document frequency),即quick在所有文档title中出现的频率,以及字段的长度,即字段越短相关度越高。

这个过程给我们的结果为:

"hits": [
 {
    "_id":      "1",
    "_score":   0.5, #1
    "_source": {
       "title": "The quick brown fox"
    }
 },
 {
    "_id":      "3",
    "_score":   0.44194174, #2
    "_source": {
       "title": "The quick brown fox jumps over the quick dog"
    }
 },
 {
    "_id":      "2",
    "_score":   0.3125, #3
    "_source": {
       "title": "The quick brown fox jumps over the lazy dog"
    }
 }
]   

1 文档1最相关,因为title更短,即quick占有内容的很大一部分。
2、3 文档3 比 文档2 更相关,因为在文档2中quick出现了2次。

  • 多词查询(Multiword Queries)
    如果我们一次只能搜索一个词,那么全文搜索会非常不灵活,幸运的是,ElasticSearch的 match 查询让多词查询非常简单:
GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": "BROWN DOG!"
        }
    }
}

上面这个查询返回了所有四个文档:

{
  "hits": [
     {
        "_id":      "4",
        "_score":   0.73185337, #1
        "_source": {
           "title": "Brown fox brown dog"
        }
     },
     {
        "_id":      "2",
        "_score":   0.47486103, #2
        "_source": {
           "title": "The quick brown fox jumps over the lazy dog"
        }
     },
     {
        "_id":      "3",
        "_score":   0.47486103, #3
        "_source": {
           "title": "The quick brown fox jumps over the quick dog"
        }
     },
     {
        "_id":      "1",
        "_score":   0.11914785, #4
        "_source": {
           "title": "The quick brown fox"
        }
     }
  ]
}

1 文档4是最为相关的,因为它包含词“brown”两次以及“dog”一次。
2#3 文档2、3同时包含brown 和 dog 各一次,而且他们title的长度相同,所以有相同的分数。
4 文档1 也能匹配,尽管它只有 brown 而没有 dog。
因为 match 查询查找两个词 [“brown”, “dog”],内部实际上它执行两次 term 查询,然后将两次查询的结果合并为最终结果输出。为了这么做,它将两个term查询合并到一个bool查询中。

这告诉我们一个重要的结果,即任何文档只要是title里面包含了任意一个词,那么就会匹配上,被匹配的词越多,最终的相关性越高。

分析器使用分析

索引时

  • 在字段映射中定义的index_analyzer,否则
  • 在字段映射中定义的analyzer,否则
  • 在文档的_analyzer中指定的analyzer,否则
  • 在type中指定的默认 index_analyzer,否则
  • 在type中指定的默认 analyzer,否则
  • 在index设置中指定的名为default_index的analyzer,否则
  • 在index设置中指定的名为default的analyzer,否则
  • 在node中指定的名为default_index的analyzer,否则
  • 在node中指定的default的analyzer,否则
  • 标准(standard)的analyzer

在搜索时

  • 在query中定义的analyzer,否则
  • 在字段映射中定义的search_analyzer,否则
  • 在字段映射中定义的analyzer,否则
  • 在type中指定的默认search_analyzer,否则
  • 在type中指定的默认analyzer,否则
  • 在index设置中指定的名为default_search的analyzer,否则
  • 在index设置中指定的名为default的analyzer,否则
  • 在node中指定的名为default_search的analyzer,否则
  • 在node中指定的名为default的analyzer,否则
  • 标准(standard)的analyzer.

phrase 匹配或者叫邻近度匹配(Proximity Matching)

短语匹配,表示有序行,如果设置slop=0,表示精确匹配。
match phrase查询首先解析字符串产生一个词条列表。然后搜索所有的词条,但只保留韩还有了所有搜索词条的文档,并且词条的位置要临近。

降低精确匹配的精度,采用slop参数。 slop参数告诉match_phrase查询词条能够相隔多远时,仍将文档视为匹配。相隔多远的意思是,需要移动一个词条多少次来让查询和文档匹配。
在配置了slop的短语匹配中,所有的单词都需要需要出现,但是单词的出现顺序可以不同。如果slop的值足够多,单面单词的顺序可以是任意的。

            Pos 1         Pos 2         Pos 3
-----------------------------------------------
Doc:        quick         brown         fox
-----------------------------------------------
Query:      fox           quick
Slop 1:     fox|quick  ↵  
Slop 2:     quick      ↳  fox
Slop 3:     quick                 ↳     fox

短语查询(Phrase Query)只是简单地将不含有精确查询短语的文档排除在外,而邻近查询(Proximity Query) - 一个slop值大于0的短语查询 - 会将查询词条的邻近度也考虑到最终的相关度_score中

通过设置一个像50或100这样的高slop值,你可以排除那些单词过远的文档,但是也给予了那些单词邻近的文档一个更高的分值。

尽管邻近度查询(Proximity Query)管用,但是所有的词条都必须出现在文档的这一要求显的过于严格了。这个问题和我们在全文搜索(Full-Text Search)一章的精度控制(Controlling Precision)一节中讨论过的类似:如果7个词条中有6个匹配了,那么该文档也许对于用户而言已经足够相关了,但是match_phrase查询会将它排除在外。

参考文档

  1. ElasticSearch文档分析系列
    http://www.cnblogs.com/richaaaard/p/5243049.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值