es基础查询(未完待续)

转自:https://mp.weixin.qq.com/s/_jXdCPGsmcpMkEnFJ5VQ7A

仅作个人备份,浏览请看原文


 

 

之前给大家介绍过elasticsearch以及它的安装,今天我们来学习一下它的基本用法

 

中文分词器

 

首先我们来了解一下中文分词器,中文分词器有两种:一种是ik_max_word,一种是ik_smart,我们分别来看下他们对中文分词的拆分

 

ik_max_word分词器

采用ik_max_word分词器,我们看到我是中国人分成了:我、是、中国人、中国、国人

 

 

 

ik_smart分词器

下面我们采用ik_smart来进行分词,同样还是对“我是中国人”这句话来进行分词,我们可以看到,采用ik_smart分词器分成了:我、是、中国人

 

 

 

我们发现,ik_max_word是一种细粒度的拆分,而ik_smart则是一种较为智能的拆分,实际使用时可根据不同场景来进行选择

 

中文分词器的github链接,最新版本已经支持到6.6.2了,更新速度还是挺快的

https://github.com/medcl/elasticsearch-analysis-ik

 

 

Rest风格

 

我们知道,elasticsearch是一套基于Rest风格的api,我们刚刚是在Kibana可视化控制台中进行的请求操作,同样的,我们可以借助postman等工具对其发起rest风格的请求,如下,也得到了我们想要的结果,所以它的使用方式是很灵活的

 

 

 

 

不过在Kibana中有很强大的语法提示,使用起来更加灵活,它的底层实现还是rest请求,只不过帮我们都封装好了

 

 

Kibana首页,界面还是挺清爽的

 

 

Kibana主页,下面的操作都是基于Dev Tools可视化控制台里面操作的

 

基本概念

 

elasticsearch的一些概念

 

索引(indices):

数据库databases

 

类型(type):

Table数据表

 

文档(Document):

Row行,每一行数据就是一个文档,类似mysql查询出来的每一行数据

 

字段(Field):

Columns列,类似mysql的每个字段

 

 

 

 

 

索引库

 

创建索引库类似于创建数据库,我们创建一个名为test的数据库,语法:

PUT /test

{

  "settings": {

    "number_of_shards": 5

    , "number_of_replicas": 1

  }

}

创建成功图示

 

 

查询索引库

GET /test

 

 

删除索引库

DELETE /test

 

 

 

创建映射字段

在test数据库下面创建一张商品表,商品表里面有3个字段,分别是title、images、price

创建语法:

 

PUT /test/_mapping/goods

{

  "properties": {

    "title":{

      "type": "text",

      "analyzer": "ik_max_word"

    },

    "images":{

      "type": "keyword",

      "index": false

    },

    "price":{

      "type": "float"

    }

  }

}

 

 

我们通过上面的语法,发现几个关键词,首先类型,文本类型有text和keyword,它们有什么区别呢,text类型的文本可以用来分词,不可用来聚合,而keyword的类型的文本不可分词,数据会作为完整的字段进行匹配,可以参与聚合

 

index代表是否索引,默认值为true,而一般图片的地址不需要检索的,所以index给设置为false

 

查看映射关系

GET /test/_mapping/goods

 

 

 

elasticsearch字段类型概述

一级分类 二级分类 具体类型

核心类型 字符串类型 text,keyword

整数类型 integer,long,short,byte

浮点类型 double,float,half_float,scaled_float

逻辑类型 boolean

日期类型 date

范围类型 range

二进制类型 binary

复合类型 数组类型 array

对象类型 object

嵌套类型 nested

地理类型 地理坐标类型 geo_point

地理地图 geo_shape

特殊类型 IP类型 ip

范围类型 completion

令牌计数类型 token_count

附件类型 attachment

抽取类型 percolator

 

添加数据

添加一条数据:

POST /test/goods

{

  "title":"小米手机",

  "images":"http://img.xiaomi.com",

   "price":2999.5

}

 

 

 

查询所有数据:

GET /test/_search

{

  "query": {

    "match_all": {}

  }

}

 

 

 

根据id查询数据:

GET /test/goods/HHzUuWkB96yUdC__j7MfGET

 

 

修改数据

根据id修改数据:

PUT /test/goods/HHzUuWkB96yUdC__j7Mf

{

   "title" : "中米手机",

   "images" : "http://img.xiaomi.com",

   "price" : 3999

}

 

 

 

put功能很强大,如果id不存在,则是新增数据

PUT /test/goods/123565

{

   "title" : "锤子手机",

   "images" : "http://img.chuizi.com",

   "price" : 1888

}

 

我们可以看到,result的返回结果,如果是修改数据,返回的updated,如果是新增数据,返回的是created,很灵活,可以代替post添加数据的功能

 

删除数据

根据id删除数据:

DELETE /test/goods/HHzUuWkB96yUdC__j7Mf

 

match查询

我们现在检索小米手机

GET /test/_search

{

  "query": {

     "match": {

       "title": "小米手机"

     }

  }

}

但是我们仔细看结果,咦?为什么华为手机,锤子手机都搜索出来了,这里注意了,我们存储的时候需要分词,搜索的时候也需要分词,我们虽然是搜索小米手机,实际上elasticsearch是拿着小米、手机这两个词去库里面检索的。所以有小米或者手机这两个词的都被检索出来了

 

 

那我们就想搜索小米手机怎么办呢?我们可以采用下面的方式(用and关系,operator指定为and)

GET /test/_search

{

  "query": {

    "match": {

      "title": {"query": "小米手机","operator": "and"}

    }

  }

}

 

 

match_all查询

查询所有数据,这个前面接演示过,这里不再赘述了,语法格式如下:

GET /test/_search

{

  "query": {

    "match_all": {}

  }

}

 

词条查询

我们用term来查询小米手机

GET /test/_search

{

  "query": {

    "term": {

      "title": {

        "value": "小米手机"

      }

    }

  }

}

 

我们发现,词条查询居然查不出小米手机,这是为什么呢?这是因为词条查询是将小米手机作为一个整体去数据库里面查询,而数据库里面的title字段都是分过词的,拿着整体去匹配分过词的数据,当然是查询不到啦!所以词条查询一般应用场景是用来去查询那些不分词的字段,例如:价格,图片地址

 

 

指定返回字段

有的时候,我们可能不需要所有的字段都返回,那我们可以用source来指定需要返回的具体字段

GET /test/_search

{

  "_source": ["title","price"],

  "query": {

    "match": {

      "title": "小米手机"

    }

  }

}

 

还有另外两种变种写法:

写法一(includes包含需要返回的字段):

GET /test/_search

{

  "_source": {

    "includes": ["title","price"]

  },

  "query": {

    "match": {

      "title": "小米手机"

    }

  }

}

写法二(excludes排除需要返回的字段):

GET /test/_search

{

  "_source": {

    "excludes": ["title","price"]

  },

  "query": {

    "match": {

      "title": "小米手机"

    }

  }

}

 

模糊查询

有一个场景,用户想搜索apple手机,但是不小心输入成applo,怎么办呢?别急,模糊查询fuzzy派上用场啦!

GET /test/_search

{

  "query": {

    "fuzzy": {

      "title": "applo"

    }

  }

}

我们看到了,即使用户输错了,我们仍然可以查询出来

 

 

指定范围查询

查询价格在3000-5000范围内的手机:

GET /test/_search

{

  "query": {

    "range": {

      "price": {

        "gte": 3000,

        "lte": 5000

      }

    }

  }

}

 

 

 

布尔查询

查询商品名为小米手机,同时价格在1000-5000范围内的商品

GET /test/_search

{

  "query": {

    "bool": {

      "must": [

        {"match": {

          "title": {"query": "小米手机","operator": "and"}

        }}

      ],

      "filter": {

        "range": {

          "price": {

            "gte": 1000,

            "lte": 5000

          }

        }

      }

    }

  }

}

 

排序

查询商品名称为手机的商品并按照价格升序排序:

GET /test/_search

{

  "query": {

    "match": {

      "title":{"query": "手机"}

    }

  },

  "sort": [

    {

      "price": {

        "order": "desc"

      }

    }

  ]

}

 

 

总结

 

基本的查询介绍完毕,下篇将着重介绍一些高级查询用法

你可能感兴趣的:(es)