ElasticSearch入门

1 简介

Elasticsearch是一个基于Apache Lucene™的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。

但是,Lucene只是一个库。想要 使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。

Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
Elasticsearch的中文网址:
https://www.elastic.co/cn/products/elasticsearch

1.1 正向索引与倒排索引

正向索引与倒排索引,这是在搜索领域中非常重要的两个名词,正向索引通常用于数据库中,在搜索引擎领域使用的最多的就是倒排索引,我们根据如下两个网页来对这两个概念进行阐述:

html1

我爱我的祖国,我爱编程

html2:

我爱编程,我是个快乐的小码农

正向索引: 假设我们使用mysql的全文检索,会对如上两句话分别进行分词处理,那么预计得到的结果如下:

我 爱 爱我 祖国 我的祖国 编程 爱编程 我爱编程
我 我爱 爱 编程 爱编程 我爱编程 快乐 码农 小码农

假设我们现在使用正向索引搜索 编程 这个词,那么会到第一句话中去查找是否包含有 编程 这个关键词,如果有则加入到结果集中;第二句话也是如此。假设现在有成千上百个网页,每个网页非常非常的分词,那么搜索的效率将会非常非常低些。

倒排索引: 倒排索引是按照分词与文档进行映射,我们来看看如果按照倒排索引的效果:

关键词文档名
html1,html2
html1,html2
爱我html1
我爱html2
祖国html1
我的祖国html1
编程html1,html2,
我爱编程html1,html2
爱编程html1,html2
快乐html2
码农html2
小码农html2

如果采用倒排索引的方式搜索 编程 这个词,那么会直接找到关键词中查找到 编程 ,然后查找到对应的文档,这就是所谓的倒排索引。

2 Elasticsearch环境搭建

下载地址:https://www.elastic.co/cn/start,在下载页面我们需要下载 Elasticsearch和Kibana.

2.1 Elasticsearch的安装

2.1.1 单机版安装

下载后解压进入到bin目录下,双击elasticsearch.bat,即可启动。在浏览器输入:http://localhost:9200/ 是否安装成功,如下图所示:
在这里插入图片描述

2.2 Kibana的安装

Kibana是世界上最受欢迎的开源日志分析平台ELK Stack中的“K” ,它为用户提供了一个工具,用于在存储于Elasticsearch集群中的日志数据进行检索,可视化和构建仪表板。

Kibana的核心功能是数据查询和分析。使用各种方法,用户可以搜索Elasticsearch中索引的数据,以查找其数据中的特定事件或字符串,以进行根本原因分析和诊断。基于这些查询,用户可以使用Kibana的可视化功能,允许用户使用图表,表格,地理图和其他类型的可视化以各种不同的方式可视化数据。

A. 下载后进入到家目录下的bin目录中,首先修改config目录下的kibana.yml文件,修改如下内容:

elasticsearch.hosts: ["http://192.168.43.240:9200", "http://192.168.223.139:9200"]

B. 进入bin目录下,双加 kibana.bat文件,在浏览器地址栏访问:http://localhost:5601
在这里插入图片描述
C. Kibana中我们使用最多的就是 Dev Tools工具,来进行所有命令的演示:
在这里插入图片描述
注:如上 GET _cat/indices 命令是查看所有的索引。

2.3 Logstash的安装

Logstash是一个开源的服务器端数据处理管道,可以同时从多个数据源获取数据,并对其进行转换,然后将其发送到你最喜欢的“存储”。创建于2009年,于2013年被elasticsearch收购。
在这里插入图片描述
Logstash的下载地址:
https://www.elastic.co/cn/downloads/logstash

A.下载测试数据集,下载地址:http://files.grouplens.org/datasets/movielens/,在该网页中下载ml-latest.zip
在这里插入图片描述
下载后解压目录,将movies.csv文件拷贝到指定的目录下,例如:D:/logstash-datas/ 目录。

B. 进入到Logstash的解压目录,进入到config目录下,新建logstash.conf,文件内容如下:

input {
  file {
    path => "D:/logstash-datas/movies.csv"
    start_position => "beginning"
    sincedb_path => "D:/logstash-datas/db_path.log"
  }
}
filter {
  csv {
    separator => ","
    columns => ["id","content","genre"]
  }

  mutate {
    split => { "genre" => "|" }
    remove_field => ["path", "host","@timestamp","message"]
  }

  mutate {

    split => ["content", "("]
    add_field => { "title" => "%{[content][0]}"}
    add_field => { "year" => "%{[content][1]}"}
  }

  mutate {
    convert => {
      "year" => "integer"
    }
    strip => ["title"]
    remove_field => ["path", "host","@timestamp","message","content"]
  }

}
output {
   elasticsearch {
     hosts => "http://192.168.31.173:9200"
     index => "movies"
     document_id => "%{id}"
   }
  stdout {}
}

C. 在命令行进入到logstash的bin目录下,输入如下命令启动Logstash:

logstash.bat -f D:\logstash-datas\config\logstash.conf


注意:路径中绝对不能有中文
D. 在Kibana的Dev Tools中执行 GET _cat/indices, 即可查看到movies数据集:
在这里插入图片描述

3 Elasticsearch的基本概念

3.1 索引、文档、类型

索引
Elasticsearch中的索引有多层的意思:a. 某一类文档的集合就构成了一个索引,类比到数据库就是一个数据库(或者数据库表);b.它还描述了一个动作,就是将某个文档保存在elasticsearch的过程也叫索引;c. 倒排索引。

文档
具体的一条数据,类比到数据库就是一条记录。
在这里插入图片描述
类型
在7.0之前,一个Index可以创建多个类型,从7.0开始,一个索引只能创建一个类型,也就是_doc

DBMSElasticsearch
databaseIndex
tabletype(在7.0之后type为固定值_doc)
RowDocument
ColumnField
SchemaMapping
SQLDSL(Descriptor Structure Language)
DBMS  	          Elasticsearch           

database Index
table type(在7.0之后type为固定值_doc)
Row Document
Column Field
Schema Mapping
SQL DSL(Descriptor Structure Language)

4 RestAPI

elasticsearch 提供了rest风格的API,通过这些API可以直接操作elasticsearch,例如对索引的增删改查操作。

查询所有的索引

GET _cat/indices

查询movies的信息

GET movies

查询movies的记录总数

GET movies/_count

查询movies的前几条数据

GET movies/_search

4.1 基本CRUD

A. 添加数据,没有指定ID, 系统会生成ID

POST user/_doc
{
  "age": 10,
  "firstName": "Will",
  "lastName": "Smith"
}

B. 操作数据,指定ID,如果有对应的ID,就修改数据;如果没有对应的ID,就添加数据

POST user/_doc/1
{
  "age": 20,
  "firstName": "Roden",
  "lastName": "Jhson"
}

C. 通过 _create 的方式,如果存在ID,就会报错

POST user/_create/2
{
  "age": 40,
  "firstName": "Douge",
  "lastName": "Lee"
}

PUT users/_create/8 
{
  "age": 50,
  "firstName":"Jacks",
  "lastName": "Lily"
}

D. 查询指定ID的文档

GET user/_doc/1

E. 删除指定ID的文档

DELETE user/_doc/2Gxqc24BJqcwPamzqWgn

F. 指定ID,创建或者覆盖

PUT user/_doc/1
{
  "age": 40,
  "firstName": "Hello",
  "lastName": "Lee"
}

G. 修改原有数据的结构

POST user/_update/1
{
  "doc": {
    "firstName":"Rodan",
    "lastName": "Johson"
  }
}

H.批量查询

GET _mget
{
  "docs": [
    {"_index":"movies", "_id":"104372"},
   {"_index":"movies", "_id":"104374"}
  ]
}

I. 分页查询

GET movies/_search
{
  "from": 0,
  "size": 20
}

J. 批量插入(可以指定ID,也可以不指定ID)

POST user/_bulk
{"index":{"_id": 23}}
{"firstName":"Will", "lastName":"Smith", "mobile": "123455"}
{"index":{}}
{"firstName":"Lily", "lastName":"Bob", "mobile": "98765"}

4.2 URI查询

A.泛查询,就是不指定字段,全字段查找,如下查找所有字段中包含有2012的电影

GET movies/_search?q=2012

B.查询title中包含有2012的所有的电影(df是default field)

GET movies/_search?q=2012&df=title
或者
GET movies/_search?q=title:2012

C.查询title中包含有2012,取索引从10开始,共8条数据

GET movies/_search?q=title:2012&from=10&size=8

D.字符串判断查询:

# 查询titile中包含有Beautiful, Mind
GET movies/_search?q=title:Beautiful Mind

#查询title中包含有Beautiful, 并且年份大于2012
GET movies/_search?q=title:Beautiful AND year:>=2012

#查询titile中包含有Beautiful或者Mind
GET movies/_search?q=title:(Beautiful Mind)
GET movies/_search?q=title:(+Mind +Beautiful)

#查询title中包含有“Beautiful Mind”的所有的电影
GET movies/_search?q=title:"Beautiful Mind"


#查询title中既包含有Mind又包含有Beautiful的所有的电影,对先后顺序没有要求
GET movies/_search?q=title:(Mind AND Beautiful)
GET movies/_search?q=title:(+Mind AND +Beautiful)

#查询title中包含Mind但是不包含Beautiful的所有的电影
GET movies/_search?q=title:(Mind NOT Beautiful)
GET movies/_search?q=title:(Mind -Beautiful)

E.年份判断查询:

#查询2018年以后上映的电影
GET movies/_search?q=year:>=2018

#查询2012年到2017年上映的电影
GET movies/_search?q=year:(>=2012 AND <2018)

#查询2016年到2017年所有的电影,注意:必须以 ] 结尾
GET movies/_search?q=year:{2015 TO 2017]

F.正则判断查询:

#查询title中以Mi开头,中间包含一个字符,以d结尾的所有的电影
GET movies/_search?q=title:Mi?d

#查询title中以Min开头,后面为任何内容的电影
GET movies/_search?q=title:Min*

4.3 Request Body查询

在有些查询中,可能会用到各种特别复杂的查询,那么就需要使用Request Body查询。

A.以year的倒序排序,查询电影年份在 [2017, 2018]的数据, query只能单条件查询

GET movies/_search
{
  "sort": [
    {
      "year": {
        "order": "desc"
      }
    }
  ],
  # query中只能有一个条件
  "query": {
    "range": {
      "year": {
        "gte": 2017,
        "lte": 2018
      }
    }
  }
}

B.以year的倒序排序,查询titile中包含有Beautiful或者Mind的数据, query只能单条件查询

GET movies/_search
{
  "sort": [
    {
      "year": {
        "order": "desc"
      }
    }
  ],
  # query中只能有一个条件
  "query": {
    "match": {
      "title": "Beautiful Mind"
    }
  }
}

C. 按照年份的倒序,分页查询

GET movies/_search
{
  "sort": [
    {
      "year": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 20
}

D. 短语匹配,查询title中包含有 “Beautiful Mind” 这个短语的的电影

GET movies/_search
{
  "query": {
    "match_phrase": {
      "title": "Beautiful Mind"
    }
  }
}

E. 只查询部分列

GET movies/_search
{
  "_source": ["title", "year"]
}

F. 多个条件查询,多条件查询必须使用bool

GET movies/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "year": {
              "gte": 2017,
              "lte": 2018
            }
          }
        },
        {
          "match": {
            "title": "Beautiful Mind"
          }
        }
      ]
    }
  }
}

G. 多字段同时匹配某些字符串

GET movies/_search
{
  "query": {
    "multi_match": {
      "query": "beautiful mind Romance",
      "fields": ["title", "genre"],
      "type": "best_fields"
    }
  }
}

其中type的值有三个:

  • most_fields:在多字段中匹配的越多排名越靠前
  • best_fields: 能完全匹配的文档,排名越靠前。
  • cross_fields: 查询越分散,排名越靠前。

H. query_string 的用法

GET movies/_search
{
  "query": {
    "query_string": {
      "default_field": "title",
      "query": "Beautiful Mind",
      "default_operator": "AND"   #不加默认是OR
    }
  }
}
GET movies/_search
{
  "query": {
    "query_string": {
      "fields": ["title", "genre"],
      "query": "Beautiful Mind",
      "default_operator": "AND"
    }
  }
}

I. term实现精准匹配,查询title为Beautiful Mind 的电影

GET movies/_search
{
  "query": {
    "term": {
      "title.keyword": {
        "value": "Beautiful Mind"
      }
    }
  }
}

J. 多条件或者判断

GET movies/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "Beautiful Mind"
          }
        },
        {
          "range": {
            "year": {
              "gte": 2017,
              "lte": 2018
            }
          }
        }
      ]
    }
  }
}

K. 推荐搜索

所谓的推荐搜索就是当我们根据条件搜索的时候,因为单词的拼写错误,但是无法搜索出结果,那么Elasticsearch会给出一定的搜索建议,通过 sugguest 来实现。

GET movies/_search
{
  "suggest": {
    "title-suggest": {
      "text": "beautifu Minx",
      "term": {
        "field": "title",
        "suggest_mode": "missing"
      }
    },
    "genre-suggest": {
       "text": "drama",
      "term": {
        "field": "genre",
        "suggest_mode": "missing"
      }
    }
  }
}

在这里插入图片描述
在这里插入图片描述
说一下suggest_mode 的三种模式:missing 、popular、always

missing: 意思是当词典中没有找到对应的索引信息,才去推荐。

popular: 意思是即使我们去搜索一个被索引了的单词,但是还是会去给我们推荐类似的但是出现频率很高的词。

always: 无论在任何情况下,都给出推荐。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值