ElasticSearch基础知识及应用实例

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: ES是基于Lucene构建的开源、分布式、RESTful接口全文搜索引擎。同时它还是一个分布式文档数据库,其中每个字段均是被索引的数据且可被搜索,便于扩展,能在短时间内搜索和分析大量数据。Lucene是一个Java全文搜索引擎;仅是一个框架,提供代码库和API,并不是完整的应用程序。咱们之前讲的处理分词,构建倒排索引,等等,都是这个叫lucene的做的。那么能不能说这个lucene就是搜索引擎呢?还不能。lucene只是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来的应用。好比lucene是类似于jdk,而搜索引擎软件就是tomcat 的。

ElasticSearch基础知识及应用实例

一、简介

ES是基于Lucene构建的开源、分布式、RESTful接口全文搜索引擎。同时它还是一个分布式文档数据库,其中每个字段均是被索引的数据且可被搜索,便于扩展,能在短时间内搜索和分析大量数据。

Lucene是一个Java全文搜索引擎;仅是一个框架,提供代码库和API,并不是完整的应用程序。咱们之前讲的处理分词,构建倒排索引,等等,都是这个叫lucene的做的。那么能不能说这个lucene就是搜索引擎呢?

还不能。lucene只是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来的应用。好比lucene是类似于jdk,而搜索引擎软件就是tomcat 的。

使用的存储数据的结构是:倒排索引;

常用匹配使用的工具:kibana 可以在客户端操作es结构、参数、数据等等;

二、应用场景

搜索,根据用户输入的关键词进行匹配,从已有的数据库中摘录出相关的记录反馈给用户。

常见的全网搜索引擎,像百度、谷歌这样的。但是除此以外,搜索技术在垂直领域也有广泛的使用,比如淘宝、京东搜索商品,万芳、知网搜索期刊,csdn中搜索问题贴。也都是基于海量数据的搜索。

日志存储,用于K8S嵌入ES做日志存储,用于页面日志内容检索;ELK方案等;

大数据分析存储、应用系统性能分析、安全指标监控等;

三、ES的基本概念

1. elasticsearch的基本概念

cluster

整个elasticsearch 默认就是集群状态,整个集群是一份完整、互备的数据。

node

集群中的一个节点,一般只一个进程就是一个node

shard

分片,即使是一个节点中的数据也会通过hash算法,分成多个片存放,默认是5片。

index

相当于rdbmsdatabase, 对于用户来说是一个逻辑数据库,虽然物理上会被分多个shard存放,也可能存放在多个node中。

type

类似于rdbms的table,但是与其说像table,其实更像面向对象中的class , 同一Json的格式的数据集合。当前使用的ES中建议一个index中只设一个type.

document

类似于rdbmsrow、面向对象里的object

field

相当于字段、属性

2. elasticsearch restful api (DSL)使用kibana进行操作

数据在Java中的格式是一个一个的对象,但是存储到es之中后,能将其之前的一个对象看成是一个JSON结构的数据,或者是一个嵌套的JSON结构。

例如:

#在Java中的结构,存储到es后的结构是JSON
//电影实例
public class  Movie {
  String id;
  String name;
  Double dazhongScore;
  List<Actor> actorList;
}
//演员实例
public class Actor{
  String id;
  String name;
}
#存储到ES后的结构如下:
{
  "id":"1",
  "name":"red sea",
  "dazhongScore":"8.5",
  "actorList":[
    {"id":"1","name":"zhangyi"},
    {"id":"2","name":"haiqing"},
    {"id":"2","name":"zhanghanyu"}
 ]
}

2.1 对数据的操作,基本的命令(执行命令的窗口在kibana的页面中,的Dev Tools下的Console中运行)

1)  查看es中有哪些索引
GET /_cat/indices?v
#注意 es中会默认存在一个名为.kibana的索引
2)删除一个索引
DELETE /index名称 例如:DELETE /movie_index
3)新增document数据,新增一条数据,命令格式:PUT /index/type/document_id 换行 {数据的JSON结构}
例如:
PUT /movie_index/movie/1
{ "id":1,
  "name":"red sea",
  "dazhongScore":8.5,
  "actorList":[  
    {"id":1,"name":"zhang yi"},
    {"id":2,"name":"hai qing"},
    {"id":3,"name":"zhang han yu"}
 ]
}
及时执行上面这个新建的命令之前没有创建index和type,也能创建数据成功,因为es会根据插入数据的内容
自动创建对应index和type的mapping文件格式,自动解析数据中的字段内容;所以,在日常的使用中如果数据的
字段数量很多,可以只指定几个特别用来检索字段的mapping类型和分词方式等,其他的字段可以不指定类型,让
es自行去创建对应的完整的mapping格式。
4)直接通过es存储数据的id进行查找。格式:GET /index_name/type_name/document_id
例如:GET/movie_index/movie/1
5)修改—整体替换,和新增没有区别,都是指定id进行的操作,如下:
PUT /movie_index/movie/1
{ "id":1,
  "name":"red sea ddd",
  "dazhongScore":9.5,
  "actorList":[  
    {"id":1,"name":"zhang yi 1"},
    {"id":2,"name":"hai qing 1"},
    {"id":3,"name":"zhang han yu 1"}
 ]
}
6) 修改—某个字段, 格式:POST movie_index/movie/1/_update 换行 {json数据}
POST movie_index/movie/1/_update
{ 
  "doc": {
    "dazhongScore":"7.0"
  } 
}
7)删除一个document数据, 格式: DELETE index_name/type_name/document_id
例如:DELETE movie_index/movie/3
8) 搜索type全部数据和结果讲解, 格式:GET index_name/type_name/_search 当前es在
没有指定查询多少条数据的时候,那es默认在kibana中展示10条数据。如果需要指定查询数量需要设置参数。
from和size两个参数。
例如:GET movie_index/movie/_search
结果字段含义:
{
  "took": 2,    //耗费时间 毫秒
  "timed_out": false, //是否超时
  "_shards": {
    "total": 5,   //发送给全部5个分片
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 3,  //命中3条数据
    "max_score": 1,   //最大评分
    "hits": [  // 结果
      {
        "_index": "movie_index",
        "_type": "movie",
        "_id": 2,
        "_score": 1,
        "_source": {
          "id": "2",
          "name": "operation meigong river",
          "doubanScore": 8.0,
          "actorList": [
            {
              "id": "1",
              "name": "zhang han yu"
            }
          ]
    }
}
9)按条件查询全部:
GET movie_index/movie/_search
{
  "query":{
    "match_all": {}
  }
}
10)按分词查询,分词匹配:
GET movie_index/movie/_search
{
  "query":{
    "match": {"name":"red"}
  }
}
11)按分词子属性查询
GET movie_index/movie/_search
{
  "query":{
    "match": {"actorList.name":"zhang"}
  }
}
12)短语匹配 match phrase,按短语查询,不再利用分词技术,直接用短语在原始数据中匹配
GET movie_index/movie/_search
{
    "query":{
      "match_phrase": {"name":"red sea"}
    }
}
13) fuzzy查询(模糊查询), 校正匹配分词,当一个单词都无法准确匹配,es通过一种算法对非常接近的单词也给与一定的评分,
能够查询出来,但是消耗更多的性能。
GET movie_index/movie/_search
{
    "query":{
      "fuzzy": {"name":"rad"}
    }
}
14)过滤--查询前过滤
GET movie_index/movie/_search
{ 
    "query":{
        "bool":{
          "filter":[ {"term": {  "actorList.id": "1"  }},
                     {"term": {  "actorList.id": "3"  }}
           ], 
           "must":{"match":{"name":"red"}}
         }
    }
}
15) 过滤--按范围过滤
GET movie_index/movie/_search
{
   "query": {
     "bool": {
       "filter": {
         "range": {
            "dazhongScore": {"gte": 8}
         }
       }
     }
   }
}
关于范围操作符:
gt  大于;lt 小于;gte  大于等于;lte  小于等于
16) 排序
GET movie_index/movie/_search
{
  "query":{
    "match": {"name":"red sea"}
  }
  , "sort": [
    {
      "dazhongScore": {
        "order": "desc"
      }
    }
  ]
}
17) 分页查询, es使用默认分页查询的时候,默认一次获取数据10000条,如果超过10000那就会在代码中报错,
需要设置对应的查询数量,设置参数max_result_window, 执行命令:
GET /movie_index/_settings  ——查看参数
PUT /movie_index/_settings   ——设置参数
{"max_result_window":1000000}
GET movie_index/movie/_search
{
  "query": { "match_all": {} },
  "from": 1,
  "size": 1
}
18)指定查询的字段,查询展示字段限制,只展示自己想要的字段
GET movie_index/movie/_search
{
  "query": { "match_all": {} },
  "_source": ["name", "dazhongScore"]
}
19) 高亮显示
GET movie_index/movie/_search
{
    "query":{
      "match": {"name":"red sea"}
    },
    "highlight": {
      "fields": {"name":{} }
    }
}
20) 聚合查询
GET movie_index/movie/_search
{ 
  "aggs": {
    "groupby_actor": {
      "terms": {
        "field": "actorList.name.keyword"  
      }
    } 
  }
}
其中的aggs代表的统计,terms表示精确匹配多个字段;groupby_actor表示按actor进行分组;
21)每个演员参演电影的平均分是多少,并按评分排序
GET movie_index/movie/_search
{ 
  "aggs": {
    "groupby_actor_id": {
      "terms": {
        "field": "actorList.name.keyword" ,
        "order": {
          "avg_score": "desc"
          }
      },
      "aggs": {
        "avg_score":{
          "avg": {
            "field": "dazhongScore" 
          }
        }
       }
    } 
  }
}
22)关于mapping文件的信息
之前说type可以理解为table,那每个字段的数据类型是如何定义的呢,查看看mapping命令:
GET index_name/type_name/_mapping
实际上每个type中的字段是什么数据类型,由mapping定义。
但是如果没有设定mapping系统会自动,根据一条数据的格式来推断出应该的数据格式。
true/false → boolean
1020  →  long
20.1 → double
“2018-02-01” → date
“hello world” → text +keyword
默认只有text会进行分词,keyword是不会分词的字符串。
mapping除了自动定义,还可以手动定义,但是只能对新加的、没有数据的字段进行定义。一旦有了数据就无法再做修改了。
注意:虽然每个Field的数据放在不同的type下,但是同一个名字的Field在一个index下只能有一种mapping定义。




2.2 使用Java语言进行dsl组装

#引入的jar包依赖
<dependency>
  <groupId>org.elasticsearch</groupId>
  <artifactId>elasticsearch</artifactId>
  <version>6.3.2</version>
</dependency>
<dependency>
  <groupId>org.elasticsearch.client</groupId>
  <artifactId>elasticsearch-rest-high-level-client</artifactId>
  <version>6.3.2</version>
</dependency>


使用的是QueryBuilders类进行操作,这个是基础的builder。日常的开发使用中有:

bool语句使用:BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

must语句使用:List<QueryBuilder> mustBuilder = boolQueryBuilder.must();
must_not语句使用:List<QueryBuilder> mustNotBuilder = boolQueryBuilder.mustNot();

should语句使用:List<QueryBuilder> should = boolQueryBuilderName.should();

filter语句使用: List<QueryBuilder> filter = boolQueryBuilder.filter();

funcation语句使用:FunctionScoreQueryBuilder;

排序sort语句使用:SearchSourceBuilder;

聚合函数的调用使用:SearchSourceBuilder的aggregation()方法进行组装等等;

2.3 es的倒排索引

es索引底层存储的数据结构是倒排索引的方式进行索引存储的,是Lucene提供的技术实现。

存储数据的结构:

倒排表以字或词为关键字进行索引,表中关键字所对应的记录表项记录了出现这个字或词的所有文档,一个表项就是一个字表段,它记录该文档的ID和字符在该文档中出现的位置情况。

由于每个字或词对应的文档数量在动态变化,所以倒排表的建立和维护都较为复杂,但是在查询的时候由于可以一次得到查询关键字所对应的所有文档,所以效率高于正排表。在全文检索中,检索的快速响应是一个最为关键的性能,而索引建立由于在后台进行,尽管效率相对低一些,但不会影响整个搜索引擎的效率。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
5月前
|
运维 监控 Java
探索Elasticsearch在Java环境下的全文检索应用实践
【6月更文挑战第30天】在大数据背景下,Elasticsearch作为分布式搜索分析引擎,因其扩展性和易用性备受青睐。本文指导在Java环境中集成Elasticsearch,涉及安装配置、使用RestHighLevelClient连接、索引与文档操作,如创建索引、插入文档及全文检索查询。此外,还讨论了高级查询、性能优化和故障排查,帮助开发者高效处理非结构化数据全文检索。
172 0
电子书阅读分享《Elasticsearch全观测技术解析与应用(构建日志、指标、APM统一观测平台)》
电子书阅读分享《Elasticsearch全观测技术解析与应用(构建日志、指标、APM统一观测平台)》
|
2月前
|
机器学习/深度学习 存储 监控
Elasticsearch 在日志分析中的应用
【9月更文第2天】随着数字化转型的推进,日志数据的重要性日益凸显。日志不仅记录了系统的运行状态,还提供了宝贵的洞察,帮助企业改进产品质量、优化用户体验以及加强安全防护。Elasticsearch 作为一个分布式搜索和分析引擎,因其出色的性能和灵活性,成为了日志分析领域的首选工具之一。本文将探讨如何使用 Elasticsearch 作为日志分析平台的核心组件,并详细介绍 ELK(Elasticsearch, Logstash, Kibana)栈的搭建和配置流程。
288 4
|
19天前
|
存储 SQL 监控
|
19天前
|
自然语言处理 监控 数据可视化
|
1月前
|
人工智能
云端问道12期-构建基于Elasticsearch的企业级AI搜索应用陪跑班获奖名单公布啦!
云端问道12期-构建基于Elasticsearch的企业级AI搜索应用陪跑班获奖名单公布啦!
174 2
|
6月前
elasticsearch使用 scroll 滚动分页实战实例
elasticsearch使用 scroll 滚动分页实战实例
265 0
|
6月前
|
缓存 关系型数据库 Java
不要将数据库中的“分库分表”理论盲目应用到 Elasticsearch
不要将数据库中的“分库分表”理论盲目应用到 Elasticsearch
51 0
|
3月前
|
存储 自然语言处理 API
Elasticsearch 在语音识别领域的应用
【8月更文第28天】随着语音助手和智能设备的普及,语音识别技术已经成为人们日常生活中不可或缺的一部分。Elasticsearch 作为一种高性能的搜索和分析引擎,在语音识别领域可以发挥重要作用,尤其是在提供快速准确的语音搜索结果方面。本文将介绍如何利用 Elasticsearch 来增强语音识别系统的搜索能力,并通过示例代码展示具体实现。
88 0
|
3月前
|
机器学习/深度学习 自然语言处理 搜索推荐
构建智能搜索应用:Elasticsearch与自然语言处理的融合
【8月更文第28天】随着大数据和人工智能技术的发展,用户对搜索应用的需求已经从简单的关键词匹配转向了更加智能化、人性化的交互方式。本文将探讨如何利用Elasticsearch和自然语言处理(NLP)技术构建一个能够理解用户意图并提供精准搜索结果的智能搜索系统。
279 0
下一篇
无影云桌面