Elasticsearch 基本介绍

Elasticsearch 基本介绍

elasticsearch是一个基于Lucene的搜索服务器,包含Windows、macOS、Linux版等,是一个实时的分布式存储、搜索、分析的引擎。也就是,这就是个类似数据库的东西,只是他和数据库不同是,它能模糊搜索。

独特的地方

相对于数据库,Elasticsearch的强大之处就是可以模糊查询, 由于经常打错字,例如like you,打成liek you. 这个使用SQL就会麻爪,但Elasticsearch 就能搜索到like you 相关的东西,如何实现的呢?

Elasticsearch的数据结构


就是Elasticsearch 会将每个单词进行去匹配,这种根据某个词(不完整的条件)再查找对应记录,叫做倒排索引。

那Elasticsearch怎么切分这些词呢?,Elasticsearch内置了一些分词器

  1. Standard Analyzer 。按词切分,将词小写
  2. Simple Analyzer。按非字母过滤(符号被过滤掉),将词小写
  3. WhitespaceAnalyzer。按照空格切分,不转小写
  4. 等等等

Elasticsearch分词器主要由三部分组成:

  1. Character Filters(文本过滤器,去除HTML)
  2. Tokenizer(按照规则切分,比如空格)
  3. TokenFilter(将切分后的词进行处理,比如转成小写)


我们输入一段文字,Elasticsearch会根据分词器对我们的那段文字进行分词(也就是图上所看到的Ada/Allen/Sara..),这些分词汇总起来我们叫做Term Dictionary,而我们需要通过分词找到对应的记录,这些文档ID保存在PostingList

在Term Dictionary中的词由于是非常非常多的,所以我们会为其进行排序,等要查找的时候就可以通过二分来查,不需要遍历整个Term Dictionary

由于Term Dictionary的词实在太多了,不可能把Term Dictionary所有的词都放在内存中,于是Elasticsearch还抽了一层叫做Term Index,这层只存储 部分 词的前缀,Term Index会存在内存中(检索会特别快)

Term Index在内存中是以FST(Finite State Transducers)的形式保存的,其特点是非常节省内存。FST有两个优点:

  1. 空间占用小。通过对词典中单词前缀和后缀的重复利用,压缩了存储空间;
  2. 查询速度快。O(len(str))的查询时间复杂度。

Elasticsearch的术语和架构

在讲解Elasticsearch的架构之前,首先我们得了解一下Elasticsearch的一些常见术语。

Index:Elasticsearch的Index相当于数据库的Table
Type:这个在新的Elasticsearch版本已经废除(在以前的Elasticsearch版本,一个Index下支持多个Type--有点类似于消息队列一个topic下多个group的概念)
Document:Document相当于数据库的一行记录
Field:相当于数据库的Column的概念
Mapping:相当于数据库的Schema的概念
DSL:相当于数据库的SQL(给我们读取Elasticsearch数据的API)

你的任何index,也就是数据,都可以随便写在这里面的node中。

使用

from elasticsearch7 import Elasticsearch, helpers
import os, time

# 引入配置文件
ELASTICSEARCH_BASE_URL = os.getenv('ELASTICSEARCH_BASE_URL')
ELASTICSEARCH_PASSWORD = os.getenv('ELASTICSEARCH_PASSWORD')
ELASTICSEARCH_NAME= os.getenv('ELASTICSEARCH_NAME')

# tips: 如果想在本地运行,请在下面一行 print(ELASTICSEARCH_BASE_URL) 获取真实的配置

# 1. 创建Elasticsearch连接
es = Elasticsearch(
    hosts=[ELASTICSEARCH_BASE_URL],  # 服务地址与端口
    http_auth=(ELASTICSEARCH_NAME, ELASTICSEARCH_PASSWORD),  # 用户名,密码
)
# 2. 定义索引名称
index_name = "demo_index"

# 3. 如果索引已存在,删除它(仅供演示,实际应用时不需要这步)
if es.indices.exists(index=index_name):
    es.indices.delete(index=index_name)

# 4. 创建索引
es.indices.create(index=index_name)

# 5. 灌库指令
actions = [
    {
        "_index": index_name,
        "_source": {
            "keywords": to_keywords(para),
            "text": para
        }
    }
    for para in paragraphs
]

# 6. 文本灌库
helpers.bulk(es, actions)

# 灌库是异步的
time.sleep(2)

这就将数据放在引擎中了。然后搜索

def search(query_string, top_n=3):
    # ES 的查询语言
    search_query = {
        "match": {
            "keywords": to_keywords(query_string)
        }
    }
    res = es.search(index=index_name, query=search_query, size=top_n)
    return [hit["_source"]["text"] for hit in res["hits"]["hits"]]

查询与之最相关的top_n = 3个数据。返回。

参考

什么是 Elasticsearch?一篇搞懂

posted @ 2024-07-30 16:48  千面客  阅读(25)  评论(0)    收藏  举报