【搜索】ElasticSearch

ElasticSearch是一个基于Lucene的全文搜索引擎,适用于blog系统文章搜索和日志分析。本文介绍了ElasticSearch的核心概念如倒排索引,详细讲解了结构化搜索(term查询、bool过滤器、range、terms)和全文搜索(match查询),并探讨了全文搜索的倒排索引原理和Analyzer在分词中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.引言

ElasticSearch是一个开源的全文搜索引擎,是一个基于Lucene的面向文档的数据库,它像mogodb一样将数据按照json格式存储,然后你就可以通过查询获取他们了。

1.1 应用场景

1.1.1 blog系统的文章搜索,

文章可以存储在数据库,数据库将文章同步到ES,用户可以通过搜索框数据搜索关键字找到相关文章。

1.1.2 日志分析

应用日志传入kafka等MQ,logstash采集处理后传入ES,通过kibana界面查询日志,通过Grafana页面观看指标等信息。

2 入门使用

安装参考,启动服务后一般监听9200端口,一般IDE可装插件ElasticSearch,连接本机后可以使用Rest API进行交互。

也可安装kibana,安装启动后http://localhost:5601/app/kibana#/dev_tools/console 有提示补全,更友好

 

1.1 核心概念

ES就是每个index中有很多的文档doc

概念含义类比数据库
index 索引具有相同结构的文档集合Database数据库
type 类型

索引的逻辑分区

一种类型被定义为具有一组公共字段的文档

7以后默认是_doc

Table表
document 文档

JSON格式的字符串,类似于mongo中的文档含义,包含kv字段

可搜索的最小单位

Row行
field 字段文档中包含零个或者多个字段,字段类似于关系数据库中表的列Column列
term 分词索引词模糊搜素的字面量?
mapping 映射类似于关系数据库中的表结构Schema表结构
Query DSLDomain Specific LanguageSQL

1.2 常用API

API样例&解释
_cluster

Get /_cluster/health      

 # 查看集群状态,绿主备正常,黄主ok无备,红主无

_cat查看索引和分配等
  

1.2.1 文档增删改查操作

操作类型api操作作用类比数据库

DDL操作

Index
mapping

PUT school创建索引创建数据库school

Put Mapping

设置索引下文档的schema

定义index的字段、类型,控制mobile字段不加索引

alter table set

增(Create)

put my_index/_create/1

{}

POST school/_doc/

{}

创建type _doc,
并添加id=10的记录

_source保存post的body

创建表_doc

insert into _doc

删(Delete)

DELETE

删除文档

curl -X DELETE 
'localhost:9200/school/_doc/10'

delete from

改(Update)

POST /school/_update/1

{}

修改id为1的文档

文档必须存在,增量更新

update school xxx=xxx where id =1

查(Read)

Get

获取文档

Get school/_doc/10

select * from school where id=10

操作响应

1.2.2 Bulk批量修改

API操作响应

1.3.3 mget 批量读取

操作获取多个index的docs

常见错误码

2.搜索_search

检索通常分为结构化检索和全文检索和其它,本文只着眼于前两种

GET /em_chinese/_search
{
  "_source": ["content","author"],         # 过滤字段,select content,auther
  "sort": [
    {
      "id": {
        "order": "asc"                    # 根据id生序排序
      }
    }
  ], 
  "from": 10,                             # 分页查询
  "size": 20, 
  "query": {
    "match": {
      "annotation": "山桃"                  #annotation字段包含
    }
  }
}

2.1 结构化

结构化检索非常类似于关系型数据库的查询,以下列数据为例,在本机插入4行数据,类似于mongo会自动创建index=my_store库和type=products的表,表中数据如下:

_idpriceproductId
110XHDK-A-1293-#fJ3
220KDKE-B-9947-#kL5
330JODL-X-1937-#pV7
430QQPX-R-3956-#aD8
curl -X POST "localhost:9200/my_store/products/_bulk?pretty" -H 'Content-Type: application/json' -d'
{ "index": { "_id": 1 }}
{ "price" : 10, "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20, "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30, "productID" : "QQPX-R-3956-#aD8" }
'

其中一条结构如下,包含了_index库、_type表、_id、_score评分和_source是Post时的数据:

{
  "_index": "my_store",
  "_type": "products",
  "_id": "1",
  "_score": 1.0,
  "_source": {
    "price": 10,
    "productID": "XHDK-A-1293-#fJ3"
  }
}

2.1.1 term查询

GET /school/_search?q=city:ShangHai

SELECT * FROM   my_store.products WHERE price = 20
{
    "term" : {
        "price" : 20
    }
}

2.1.2 bool过滤器

bool后间的对象可以包含多个must、should、must not字段,must必须匹配=AND、must not=not

should后边的列表中表示多个条件中or关系

SELECT product
FROM   products
WHERE  (price = 20 OR productID = "XHDK-A-1293-#fJ3")
  AND  (price != 30)
GET /my_store/products/_search
{
   "query" : {
      "filtered" : { 
         "filter" : {
            "bool" : {
              "should" : [
                 { "term" : {"price" : 20}}, 
                 { "term" : {"productID" : "XHDK-A-1293-#fJ3"}} 
              ],
              "must_not" : {
                 "term" : {"price" : 30} 
              }
           }
         }
      }
   }
}

2.1.3 range

range可以比较数字、字符串字段。

SELECT document
FROM   products
WHERE  price BETWEEN 20 AND 40
"range" : {
    "price" : {
        "gte" : 20,
        "lte" : 40
    }
}

2.1.4 terms

select * from products where price in (20,30)
{
    "terms" : {
        "price" : [20, 30]
    }
}

2.2 全文搜索

以my_index/my_type为例,仅有一个字段title,是个较长的文本串,string是个analyzed已分析的字段

_idtitle
1The quick brown fox
2The quick brown fox jumps over the lazy dog
3The quick brown fox jumps over the quick dog
4Brown fox brown dog

2.2.1 match查询

单个词查询

GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": "QUICK!"
        }
    }
}

1.检查字段类型:title是string全文字段

2.分析查询字符串:QUICK!传入分析器,单个项quick,底层使用term查询

3.查找:用term在倒排索引中查找quick,返回包含其的文档

4.评分:计算文档的相关度评分_score,与词频、反向文档频率、字段长度有关。

返回id :1、2、3号文档,都包含quick这个iterm

也可以多个词查询:

GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": "BROWN DOG!"
        }
    }
}

3. 全文搜索原理

全文搜索(full-text search) :怎样在全文字段中搜索到最相关的文档。

ES的json文档默认每个字段都有自己的倒排索引,可以指定对某些字段不做索引来节省空间,但是这样的话这个字段就不能被搜索到了。

全文搜索时,根据条件分词term,再用term去索引中查找,找到对应的文档,进行相关性计算算出一个score,可以根据score进行过滤或者排序。

3.1 倒排索引(inverted index)

领域\类型正排倒排
图书目录页index关键词索引页
搜索引擎根据id索引到文档内容根据文档中单词索引到文档id

以下图为例,左侧是个正排索引,有3个文档,建立倒排索引先对句子分词term,分完词后对term进行排序,unic group后就产生了从term分词到文档的映射关系。

索引组成

  1. 单词词典term dict  :记录所有单词,及倒排列表的关联关系
  2. 倒排列表posting List: 文档id+词频TF+position+偏移offset 列表

3.1.1 分词 Analyzer

ES的Analysis也叫分词,将文本转换为一系列单词的过程,是通过Analyzer分析器来实现的,ES有内置的,也可以按需定制。

为了更好的匹配,需要确保在写入数据时用的分析器和查询所使用的一致,否则搜索效果不好

分析器包含3个部分,

组件功能
Character Filter处理原始文本,过滤一些html标签等
Tokenizer按照规则切分为单词
Token Filter对单词加工,小写,增加同义词等等

ES的内置分词器

Analyzer功能
Standard默认,按词切分,转小写
Simple按非字母切分,小写处理
Stop小写,停用词(the a is)过滤
Whitespace空格切分,不转小写
Keyword不分词
Patter正则,非字符分割
Language常见语言
Customer自定义

中文分词

analysis-icu插件提供了unicode支持,更好地支持亚洲语言,需要安装。

bin/elasticsearch-plugin install analysis-icu

还有其它的中文分词器,IK、Thulac等等。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值