注意:以下都是基于ES6操作的

准备数据

PUT /web/info/1
{
  "post_date": "2018-11-01",
  "title": "the first info",
  "content": "the first info in this web",
  "author_id": "xlucas"
}
PUT /web/info/2
{
  "post_date": "2018-11-02",
  "title": "the second info",
  "content": "the second  in this web",
  "author_id": "xlucas"
}
PUT /web/info/3
{
  "post_date": "2018-11-03",
  "title": "the third info",
  "content": "the third info in this web",
  "author_id": "xlucas"
}

在ES5和ES6里面查询的结果是不一样的,_all可能不再为在6.0+中创建的索引启用,所以这个?q=2018 不再是查询所有字段了

GET /web/info/_search       3条记录
GET /web/info/_search?q=2018    0条记录
GET /web/info/_search?q=2018-11-01   1条记录
GET /web/info/_search?q=post_date:2018-11-01  1条记录
GET /web/info/_search?q=post_date:2018   0条记录

GET /web/_mapping/info
{
  "web": {
    "mappings": {
      "info": {
        "properties": {
          "author_id": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "content": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "post_date": {
            "type": "date"
          },
          "title": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

设置了不同的field不同的data type。不同的data type的分词、搜索等行为是不一样的。所以出现了_all field和post_date field的搜索表现完全不一样。

字段类型:
精准匹配:exact value,例如字段date类型是这种精准匹配的
2018-11-01,exact value,搜索的时候,必须输入2018-11-01,才能搜索出来
如果你输入一个01,是搜索不出来的

全文检索:full text 文本是全文检索
(1)缩写 vs. 全程:cn vs. china
(2)格式转化:like liked likes
(3)大小写:Tom vs tom
(4)同义词:like vs love
例如:
2018-11-01,2018 11 01,搜索2018,或者01,都可以搜索出来

china,搜索cn,也可以将china搜索出来
 likes,搜索like,也可以将likes搜索出来
 Tom,搜索tom,也可以将Tom搜索出来
 like,搜索love,同义词,也可以将like搜索出来

就不是说单纯的只是匹配完整的一个值,而是可以对值进行拆分词语后(分词)进行匹配,也可以通过缩写、时态、大小写、同义词等进行匹配

mapping的特性

  1. mapping中就自动定义了每个field的数据类型
  2. 不同的数据类型(比如说text和date),可能有的是exact value,有的是full text
  3. exact value,在建立倒排索引的时候,分词的时候,是将整个值一起作为一个关键词建立到倒排索引中的;full text,会经历各种各样的处理,分词,normaliztion(时态转换,同义词转换,大小写转换),才会建立到倒排索引中
  4. exact value和full text类型的field就决定了,在一个搜索过来的时候,对exact value field或者是full text field进行搜索的行为也是不一样的
  5. 可以用es的dynamic mapping,让其自动建立mapping,包括自动设置数据类型;也可以提前手动创建index和type的mapping,自己对各个field进行设置,包括数据类型,包括索引行为,包括分词器,等等
  6. 只能创建index时手动建立mapping,或者新增field mapping,但是不能update field mapping

核心的数据类型

text
 byte,short,integer,long
 float,double
 boolean
 date

ES自动推测出来的类型

true or false --> boolean
 123 --> long
 123.45 --> double
 2017-01-01 --> date
 “hello world” --> keyword/text ES6没有string类型了

查看mapping

GET /index/_mapping/type

建立索引类别

analyzed --能被分词
 not_analyzed --不能被分词
 no --不能被检索

创建index指定类型

PUT /web1
{
  "mappings": {
    "article": {
      "properties": {
        "author_id": {
          "type": "text"
        },
        "title": {
          "type": "text",
          "analyzer": "english"
        },
        "content": {
          "type": "text"
        },
        "post_date": {
          "type": "date"
        },
        "publisher_id": {
          "type": "text",
          "index": false  --默认是false
        }
      }
    }
  }
}

已经存在的type是不能被修改的。

PUT /website
{
  "mappings": {
    "article": {
      "properties": {
        "author_id": {
          "type": "date"
        }
      }
    }
  }
}

出现的错误

{
  "error": {
    "root_cause": [
      {
        "type": "resource_already_exists_exception",
        "reason": "index [website/dH9_8DSKRiidy9ZoNbEkXQ] already exists",
        "index_uuid": "dH9_8DSKRiidy9ZoNbEkXQ",
        "index": "website"
      }
    ],
    "type": "resource_already_exists_exception",
    "reason": "index [website/dH9_8DSKRiidy9ZoNbEkXQ] already exists",
    "index_uuid": "dH9_8DSKRiidy9ZoNbEkXQ",
    "index": "website"
  },
  "status": 400
}

增加一个字段表示不分词的

PUT /web1/_mapping/article
{
  "properties" : {
    "new_field1" : {
      "type" :"keyword",  --类型
      "index":true   --不分词
    }
  }
}

可以用这个测试

GET /web1/_analyze
{
  "field": "new_field1",
  "text": "my-dogs" 
}