数万字长文带你入门elasticsearch(二)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 数万字长文带你入门elasticsearch

Mapping


  • 类似数据库中的表结构定义,主要作用如下:
  • 定义Index下的字段名(Field Name)
  • 定义字段的类型,比如数值型、字符串型、布尔型等
  • 定义倒排索引相关的配置,比如是否索引、记录position等。


自定义mapping


  • 自定义mapping的api如下所示:


PUT my_index
{
  "mappings":{
 "doc":{
   "properties":{
  "title":{
    "type":"text"
  },
  "name":{
    "type":"keyword"
  },
  "age":{
    "type":"integer"
  }
   }
 }
  }
}


  • Mapping中的字段类型一旦设定后,禁止直接修改,原因如下:
  • Lucene实现的倒排索引生成后不允许修改


  • 重新建立新的索引,然后做reindex操作
  • 允许新增字段
  • 通过dynamic参数来控制字段的新增
  • true(默认)允许自动新增字段
  • false不允许自动新增字段,但是文档可以正常写入,但无法对字段进行查询等操作
  • strict文档不能写入,报错


copy_to参数


  • copy_to
  • 将该字段的值复制到目标字段,实现类似_all的作用
  • 不会出现在_source中,只用来搜索


PUT my_index
{
  "mappings":{
 "doc":{
   "properties":{
  "first_name":{
    "type":""text",
    "copy_to":"full_name"
  },
  "last_name":{
    "type":"text",
    "copy_to":"full_name"
  },
  "full_name":{
    "type":"text"
  }
   }
 }
  }
}


index参数


  • index
  • 控制当前字段是否索引,默认为true,即记录索引,false不记录,即不可搜索


PUT my_index
{
  "mappings":{
 "doc":{
   "properties":{
  "cookie":{
    "type":"text",
    "index":"false"
  }
   }
 }
  }
}


index_options参数


  • index_options用于控制倒排索引记录的内容,有如下4中配置
  • docs只记录doc id
  • freqs记录doc id和term frequencies
  • positions记录doc id、term frequencies和term position
  • offsets记录doc id、term frequencies、term position和character offsets


  • text类型默认配置为positions,其他默认为docs
  • 记录内容越多,占用空间越大
  • indexoptions设定如下所示:


PUT my_index
{
  "mappings":{
 "doc":{
   "properties":{
  "cookies":{
    "type":"text",
    "index_options":"offsets"
  }
   }
 }
  }
}


  • null_value
  • 当字段遇到null值时的处理策略,默认为null,即空值,此时es会忽略该值。可以通过设定该值设定字段的默认值


PUT my_index
{
  "mappings":{
 "my_type":{
   "properties":{
  "status_code":{
    "type":"keyword",
    "null_value":"NULL"
  }
   }
 }
  }
}


数据类型


  • 核心数据类型
  • 字符串:text,keyword
  • 数值型:long,integer,short,byte,double,float,half_float,scaled_float
  • 布尔:boolean
  • 日期:date
  • 二进制:binary
  • 范围类型:integer_range,float_range,long_range,double_range,date_range
  • 复杂数据类型
  • 数组类型array
  • 对象类型object
  • 嵌套类型nested object
  • 地理位置数据类型
  • geo_point
  • geo_shape
  • 专用类型
  • 记录ip地址ip
  • 实现自动补全completion
  • 记录分词数token_count
  • 记录字符串hash值murmur3
  • percolator
  • join
  • 多字段特性
  • 允许对同一个字段采用不同的配置,比如分词,常见例子如对人名实现拼音搜素,只需要在人名中新增一个子字段为pinyin即可


{
  "test_index":{
 "mappings":{
   "doc":{
  "properties":{
    "username":{
   "type":"text",
   "fields":{
     "pinyin":{
    "type":"text",
    "analyzer":"pinyin"
     }
   }
    }
  }
   }
 }
  }
}


Dynamic Mapping


  • es可以自动识别文档字段类型,从而降低用户使用成本
  • es是依靠json文档的字段类型来实现自动识别字段类型,支持的类型如下:


JSON类型 es类型
null 忽略
Boolean Boolean
浮点类型 float
整数 long
object object
array 有第一个非null值的类型决定
string 匹配为日期则设为date类型(默认开启),匹配为数字的话设为float或long类型(默认关闭),设为text类型,并附带keyword的子字段


dynamic日期与数字识别


  • 日期的自动识别可以自行配置日期格式,以满足各种需求


  • YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-20T15;30:50 +01:00)
  • 默认是["strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy /MM/dd Z"]
  • strict_date_optional_time是ISO datetime的格式,完整格式类似下面:
  • dynamic_date_formats可以自定义日期类型
  • date_detection可以关闭日期自动识别的机制


PUT mu_index
{
  "mappings":{
 "my_type":{
   "dynamic_date_formats":["MM/dd/yyyy"],
   "date_detection":false
 }
  }
}


  • 字符串是数字时,默认不会自动识别为整型,因为字符串中出现数字是完全合理的
  • numeric_detection可以开启字符串中数字的自动识别,如下所示:


PUT my_index
{
  "mappings":{
 "my_type":{
   "numeric_detection":true
 }
  }
}


Dynamic Templates


  • 允许根据es自动识别的数据类型、字段名等来动态设定字段类型,可以实现如下效果:
  • 所有字符串类型都设定为keyword类型,即默认不分词
  • 所有以message开头的字段都设定为text类型,即分词
  • 所有以long_开头的字段都设定为long类型
  • 所有自动分配为double类型的都设定为float类型,以节省空间


  • API如下所示:


PUT test_index
{
  "mappings":{
 "doc":{
   "dynamic_templates":[#数组,可指定多个匹配规则
  {
    "strings":{ #模板名称
   "match_mapping_type":"string",#匹配规则
   "mapping":{
     "type":"keyword"
   }
    }
  }
   ]
 }
  }
}


  • 匹配规则一般有如下几个参数:
  • match_mapping_type匹配es自动识别的字段类型,如Boolean,long,string等
  • match,unmatch匹配字段名
  • path_match,path_unmatch匹配路径


自定义mapping的建议


  • 自定义Mapping的操作步骤如下:
  1. 写入一条文档到es的临时索引中,获取es自动生成的mapping
  2. 修改步骤1得到的mapping,自定义相关配置
  3. 使用步骤2的mapping创建实际所需索引


首先创建一个文档


PUT my_index/doc/1
{
  "referrer": "-",
  "response":"200",
  "remote_ip":"171.22.12.14",
  "method":"POST",
  "user_name":"-",
  "http_version":"1.1",
  "body_sent":{
    "bytes":"0"
  },
  "url":"/analyzeVideo"
}


es会根据创建的文档动态生成映射,可以直接将动态生成的映射直接复制到需要自定义的mapping中


PUT test_index
{
  "mappings": {
      "doc": {
        "properties": {
          "body_sent": {
            "properties": {
              "bytes": {
                "type": "long"
              }
            }
          },
          "http_version": {
            "type": "keyword"
          },
          "method": {
            "type": "keyword"
          },
          "referrer": {
            "type": "keyword"
          },
          "remote_ip": {
            "type": "keyword"
          },
          "response": {
            "type": "long"
          },
          "url": {
            "type": "text"
          },
          "user_name": {
            "type": "keyword"
          }
        }
      }
  }
}


这样定义的映射还是比较多余,可以利用动态模板将string类型直接替换成keyword


DELETE test_index
PUT test_index
{
  "mappings": {
      "doc": {
        "dynamic_templates":[
          {
            "strings":{
              "match_mapping_type":"string",
              "mapping":{
                "type":"keyword"
              }
            }
          }  
        ],
        "properties": {
          "body_sent": {
            "properties": {
              "bytes": {
                "type": "long"
              }
            }
          },
          "response": {
            "type": "long"
          },
          "url": {
            "type": "text"
          }
        }
      }
  }
}


索引模板


  • 索引模板,主要用于在新建索引时自动应用预先设定的配置,简化索引创建的操作步骤
  • 可以设定索引的配置和mapping
  • 可以有多个模板,根据order设置,order搭的覆盖小的配置


索引模板API如下所示:


PUT _template/test_template
{
  "index_patterns":["te*","bar*"],
  "order":0,
  "settings":{
   "number_of_shards":1,
   "number_of_replicas":0
  },
  "mappings":{
    "doc":{
      "_source":{
        "enabled":false
      },
      "properties":{
        "name":{
          "type":"keyword"
        }
      }
    }
  }
}


  • "index_paterns":匹配的索引名称
  • "order":匹配的优先级
  • "settings":索引的配置


search API


  • 查询有两种形式:
  • es提供完备的查询语法Query DSL
  • 操作简单,方便通过命令行测试
  • 仅包含部分查询语法
  • URI search
  • Request Body Search


URI Search


  • 通过url query参数来实现搜索,常用参数如下:
  • q 指定查询的语句,语法为Query String Syntax
  • df q中不指定字段时默认查询的字段,如果不指定es会查询所有字段
  • sort 排序
  • timeout 指定超时时间,默认不超时
  • from,size用于分页


URI Search - Query String Syntax


  • term与phrase
  • alfred  way 等效于Alfred OR way
  • "alfred way" 词语查询,要求先后顺序
  • 泛查询
  • alfred 等效于在所有字段去匹配该term
  • 指定字段
  • name:alfred
  • Group分组设定,使用括号指定匹配的规则
  • (quick OR brown) AND fox
  • status:(active OR pending) title:(full text search)
  • 布尔操作符
  • name:(tom NOT lee)
  • 注意大写,不能小写
  • AND(&&),OR(||),NOT(!)
  • +—分别对应must和must_not
  • name:(tom +lee -alfred) #返回一定包含lee,可以包含tom,一定不包含alfred的文档
  • name:((lee && !alfred)) || (tom && lee && !alfred)
  • +在url中会被解析为空格,要使用encode后的结果才可以,为%2B
  • 范围查询,支持数值和日期
  • age:>=1
  • age:(>=1 && <=10) 或者age:(+>=1 +<=10)
  • age:[1 TO 10] 意为1<=age<=10
  • age:[1 TO 10} 意为1<=age<10
  • age:[1 TO] 意为age>=1
  • age:[* TO 10] 意为age<=10
  • 区间写法,闭区间用[],开区间用{}
  • 算数符号写法
  • 通配符查询
  • name:t?m
  • name:tom*
  • name:t*m
  • 通配符匹配执行效率低,且占用较多内存,不建议使用
  • 如无特殊需求,不要将?/*放在最前面
  • ?代表1个字符,*代表0或多个字符
  • 正则表达式匹配
  • name:/[mb]oat/
  • 模糊匹配fuzzy query
  • name:roam~1
  • 匹配与roam差一个character的词,比如foam roams等
  • 近似度查询 proximity search
  • "fox quick" ~5
  • 以term为单位进行差异比较,比如"quick fox" "quick brown fox"都会被匹配


Query DSL


  • 基于json定义的查询语句,主要包含如下两种类型:
  • 如bool查询等,包含一个或多个字段类查询或者复合查询语句
  • 如term,match,range等,只针对某一个字段进行查询
  • 字段类查询:
  • 复合查询


Query DSL 字段类查询


  • 字段类查询主要包括以下两类:
  • 不会对查询语句做分词处理,直接去匹配字段的倒排索引,如term.terms,range等query类型
  • 针对text 类型的字段进行全文检索,会对查询语言先进行分词处理,如match,match_phrase等query类型
  • 全文匹配
  • 单词匹配


Match Query


  • 对字段作全文检索,最基本和常用的查询类型,API示例如下:


GET test_index/_search
{
  "query":{
    "match":{   #关键词
      "remote_ip":"171.22.12.14" #字段名
    }
  }
}


响应结果如下:


{
  "took": 4, #查询总用时
  "timed_out": false, #是否超时
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1, #匹配文档总数
    "max_score": 0.2876821,
    "hits": [  #返回文档列表
      {
        "_index": "test_index_index",
        "_type": "doc",
        "_id": "1",
        "_score": 0.2876821,  #文档相关度得分
        "_source": { #文档原始内容
          "referrer": "-",
          "response": "200",
          "remote_ip": "171.22.12.14",
          "method": "POST",
          "user_name": "-",
          "http_version": "1.1",
          "body_sent": {
            "bytes": "0"
          },
          "url": "/analyzeVideo"
        }
      }
    ]
  }
}


  • 通过operator参数可以控制单词间的匹配关系,可选项为or和and
  • 通过minimum_should_match参数可以控制需要匹配的单词数


Match Query -流程


首先对查询语句进行分词,分词后分别根据字段的倒排索引进行匹配算分,并会匹配到一个或多个文档,再将匹配到的文档进行汇总得分,根据得分排序返回多个文档


Match Phrase Query


  • 对字段做检索,有顺序要求,API示例如下:


GET test_index_index/_search
{
  "query":{
    "match_phrase":{
      "remote_ip":"171.22.12.14"
    }
  }
}


  • 通过slop参数可以控制单词间的间隔


Query String Query


  • 类似于URI Search中的q参数查询


GET test_index_index/_search
{
  "query":{
    "query_string":{
      "default_field":"remote_ip",
      "query":"171.22.12.14"     
    }
  }
}


Simple Query String Query


  • 类似Query String,但是会忽略错误的查询语法,并且仅支持部分查询语法
  • 其常用的逻辑符号如下,不能使用AND、OR、NOT等关键词:
  • +代指AND
  • |代指OR
  • -代指NOT 常用API如下所示:


GET test_index_index/_search
{
  "query":{
    "simple_query_string":{
      "fields":["remote_ip"],
      "query":"alfred +way"
    }
  }
}


Term Query
  • 将查询语句作为整个单词进行查询,即不对查询语句做分词处理,如下所示:


GET test_index_index/_search
{
  "query":{
    "term":{
      "remote_ip":"171.22.12.14"
    }
  }
}


Range Query
  • 范围查询主要针对数值和日期类型,如下所示:


GET test_index_index/_search
{
  "query":{
    "range":{
      "response":{#找出响应状态码大于10,小于300的文档
        "gt": 10,
        "lte":300
      }
    }
  }
}


针对日期的查询如下所示:


GET test_index_index/_search
{
  "query":{
    "range":{
      "birth":{
        "gt": "1990-01-01",
        "lte":"now-2h",
        "gt":"2019-01-01||+1M/d"
      }
    }
  }
}


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
3月前
|
安全 Linux 开发工具
Elasticsearch 搜索入门技术之一
Elasticsearch 搜索入门技术之一
227 1
|
4月前
|
JSON 自然语言处理 数据库
数据库-ElasticSearch入门(索引、文档、查询)
数据库-ElasticSearch入门(索引、文档、查询)
285 0
|
7月前
|
监控 搜索推荐 Java
elasticsearch入门实战
elasticsearch入门实战
62 1
|
6月前
|
存储 关系型数据库 数据库
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
|
2月前
|
存储 关系型数据库 MySQL
ElasticSearch 入门
【2月更文挑战第7天】ElasticSearch 入门 简介 ElasticSearch 的基本概念 ElasticSearch 的查询流程 ElasticSearch 的更新流程
36 2
|
2月前
|
存储 自然语言处理 搜索推荐
ElasticSearch入门篇
ElasticSearch入门篇
|
6月前
|
存储 JSON 定位技术
Elasticsearch入门
Elasticsearch入门
|
7月前
|
存储 JSON 搜索推荐
Elasticsearch(一)基础入门
Elasticsearch 是一个实时的分布式搜索分析引擎, 它能让你以前所未有的速度和规模,去探索你的数据。 它被用作全文检索、结构化搜索、分析以及这三个功能的组合:
36 0
|
4月前
|
存储 Java 网络架构
Spring Data Elasticsearch基础入门详解
Spring Data Elasticsearch基础入门详解
119 0
|
4月前
|
存储 数据挖掘 Java
Elasticsearch基础入门与安装部署
Elasticsearch基础入门与安装部署
167 0

热门文章

最新文章