learn.lianglianglee.com/专栏/ElasticSearch知识体系详解/14 原理:ES原理知识点补充和整体结构.md.html
2022-05-11 18:52:13 +08:00

839 lines
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>14 原理ES原理知识点补充和整体结构.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/专栏/ElasticSearch知识体系详解/01 认知ElasticSearch基础概念.md">01 认知ElasticSearch基础概念.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/02 认知Elastic Stack生态和场景方案.md">02 认知Elastic Stack生态和场景方案.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/03 安装ElasticSearch和Kibana安装.md">03 安装ElasticSearch和Kibana安装.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/04 入门:查询和聚合的基础使用.md">04 入门:查询和聚合的基础使用.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/05 索引:索引管理详解.md">05 索引:索引管理详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/06 索引:索引模板(Index Template)详解.md">06 索引:索引模板(Index Template)详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/07 查询DSL查询之复合查询详解.md">07 查询DSL查询之复合查询详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/08 查询DSL查询之全文搜索详解.md">08 查询DSL查询之全文搜索详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/09 查询DSL查询之Term详解.md">09 查询DSL查询之Term详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/10 聚合聚合查询之Bucket聚合详解.md">10 聚合聚合查询之Bucket聚合详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/11 聚合聚合查询之Metric聚合详解.md">11 聚合聚合查询之Metric聚合详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/12 聚合聚合查询之Pipline聚合详解.md">12 聚合聚合查询之Pipline聚合详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/13 原理从图解构筑对ES原理的初步认知.md">13 原理从图解构筑对ES原理的初步认知.md.html</a>
</li>
<li>
<a class="current-tab" href="/专栏/ElasticSearch知识体系详解/14 原理ES原理知识点补充和整体结构.md">14 原理ES原理知识点补充和整体结构.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/15 原理ES原理之索引文档流程详解.md">15 原理ES原理之索引文档流程详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/16 原理ES原理之读取文档流程详解.md">16 原理ES原理之读取文档流程详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/17 优化ElasticSearch性能优化详解.md">17 优化ElasticSearch性能优化详解.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/18 大厂实践:腾讯万亿级 Elasticsearch 技术实践.md">18 大厂实践:腾讯万亿级 Elasticsearch 技术实践.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/19 资料Awesome Elasticsearch.md">19 资料Awesome Elasticsearch.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/20 WrapperQuery.md">20 WrapperQuery.md.html</a>
</li>
<li>
<a href="/专栏/ElasticSearch知识体系详解/21 备份和迁移.md">21 备份和迁移.md.html</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>14 原理ES原理知识点补充和整体结构</h1>
<h2>ElasticSearch整体结构</h2>
<blockquote>
<p>通过上文在通过图解了解了ES整体的原理后我们梳理下ES的整体结构</p>
</blockquote>
<p><img src="assets/es-th-2-3.png" alt="img" /></p>
<ul>
<li>一个 ES Index 在集群模式下,有多个 Node (节点)组成。每个节点就是 ES 的Instance (实例)。</li>
<li>每个节点上会有多个 shard (分片), P1 P2 是主分片, R1 R2 是副本分片</li>
<li>每个分片上对应着就是一个 Lucene Index底层索引文件</li>
<li>Lucene Index 是一个统称
<ul>
<li>由多个 Segment (段文件,就是倒排索引)组成。每个段文件存储着就是 Doc 文档。</li>
<li>commit point记录了所有 segments 的信息</li>
</ul>
</li>
</ul>
<h2>补充:Lucene索引结构</h2>
<blockquote>
<p>上图中Lucene的索引结构中有哪些文件呢</p>
</blockquote>
<p><img src="assets/es-th-2-2.png" alt="img" /></p>
<p>(更多文件类型可参考<a href="https://lucene.apache.org/core/7_2_1/core/org/apache/lucene/codecs/lucene70/package-summary.html#package.description">这里 </a></p>
<p><img src="assets/es-th-3-1.png" alt="img" /></p>
<p>文件的关系如下:</p>
<p><img src="assets/es-th-3-2.jpeg" alt="img" /></p>
<h2>补充:Lucene处理流程</h2>
<blockquote>
<p>上文图解过程还需要理解Lucene处理流程, 这将帮助你更好的索引文档和搜索文档。</p>
</blockquote>
<p><img src="assets/es-th-3-21.jpeg" alt="img" /></p>
<p>创建索引的过程:</p>
<ul>
<li>准备待索引的原文档,数据来源可能是文件、数据库或网络</li>
<li>对文档的内容进行分词组件处理形成一系列的Term</li>
<li>索引组件对文档和Term处理形成字典和倒排表</li>
</ul>
<p>搜索索引的过程:</p>
<ul>
<li>对查询语句进行分词处理形成一系列Term</li>
<li>根据倒排索引表查找出包含Term的文档并进行合并形成符合结果的文档集</li>
<li>比对查询语句与各个文档相关性得分,并按照得分高低返回</li>
</ul>
<h2>补充:ElasticSearch分析器</h2>
<blockquote>
<p>上图中很重要的一项是<strong>语法分析/语言处理</strong>, 所以我们还需要补充ElasticSearch分析器知识点。</p>
</blockquote>
<p>分析 包含下面的过程:</p>
<ul>
<li>首先,将一块文本分成适合于倒排索引的独立的 词条 </li>
<li>之后,将这些词条统一化为标准格式以提高它们的“可搜索性”,或者 recall</li>
</ul>
<p>分析器执行上面的工作。 分析器 实际上是将三个功能封装到了一个包里:</p>
<ul>
<li><strong>字符过滤器</strong> 首先,字符串按顺序通过每个 字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML或者将 &amp; 转化成 and。</li>
<li><strong>分词器</strong> 其次,字符串被 分词器 分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。</li>
<li><strong>Token 过滤器</strong> 最后,词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条(例如,小写化 Quick ),删除词条(例如, 像 a and the 等无用词),或者增加词条(例如,像 jump 和 leap 这种同义词)。</li>
</ul>
<p>Elasticsearch提供了开箱即用的字符过滤器、分词器和token 过滤器。 这些可以组合起来形成自定义的分析器以用于不同的目的。</p>
<h3>内置分析器</h3>
<p>Elasticsearch还附带了可以直接使用的预包装的分析器。接下来我们会列出最重要的分析器。为了证明它们的差异我们看看每个分析器会从下面的字符串得到哪些词条</p>
<pre><code class="language-bash">&quot;Set the shape to semi-transparent by calling set_trans(5)&quot;
</code></pre>
<ul>
<li><strong>标准分析器</strong></li>
</ul>
<p>标准分析器是Elasticsearch默认使用的分析器。它是分析各种语言文本最常用的选择。它根据 Unicode 联盟 定义的 <strong>单词边界</strong> 划分文本。删除绝大部分标点。最后,将词条小写。它会产生</p>
<pre><code class="language-bash">set, the, shape, to, semi, transparent, by, calling, set_trans, 5
</code></pre>
<ul>
<li><strong>简单分析器</strong></li>
</ul>
<p>简单分析器在任何不是字母的地方分隔文本,将词条小写。它会产生</p>
<pre><code class="language-bash">set, the, shape, to, semi, transparent, by, calling, set, trans
</code></pre>
<ul>
<li><strong>空格分析器</strong></li>
</ul>
<p>空格分析器在空格的地方划分文本。它会产生</p>
<pre><code class="language-bash">Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
</code></pre>
<ul>
<li><strong>语言分析器</strong></li>
</ul>
<p>特定语言分析器可用于 很多语言。它们可以考虑指定语言的特点。例如, 英语 分析器附带了一组英语无用词(常用单词,例如 and 或者 the ,它们对相关性没有多少影响),它们会被删除。 由于理解英语语法的规则,这个分词器可以提取英语单词的 词干 。</p>
<p>英语 分词器会产生下面的词条:</p>
<pre><code class="language-bash">set, shape, semi, transpar, call, set_tran, 5
</code></pre>
<p>注意看 transparent、 calling 和 set_trans 已经变为词根格式。</p>
<h3>什么时候使用分析器</h3>
<p>当我们 索引 一个文档,它的全文域被分析成词条以用来创建倒排索引。 但是,当我们在全文域 搜索 的时候,我们需要将查询字符串通过 相同的分析过程 ,以保证我们搜索的词条格式与索引中的词条格式一致。</p>
<p>全文查询,理解每个域是如何定义的,因此它们可以做正确的事:</p>
<ul>
<li>当你查询一个 全文 域时, 会对查询字符串应用相同的分析器,以产生正确的搜索词条列表。</li>
<li>当你查询一个 精确值 域时,不会分析查询字符串,而是搜索你指定的精确值。</li>
</ul>
<blockquote>
<p>举个例子</p>
</blockquote>
<p>ES中每天一条数据 按照如下方式查询:</p>
<pre><code class="language-bash">GET /_search?q=2014 # 12 results
GET /_search?q=2014-09-15 # 12 results !
GET /_search?q=date:2014-09-15 # 1 result
GET /_search?q=date:2014 # 0 results !
</code></pre>
<p>为什么返回那样的结果?</p>
<ul>
<li>date 域包含一个精确值:单独的词条 2014-09-15。</li>
<li>_all 域是一个全文域,所以分词进程将日期转化为三个词条: 2014 09 和 15。</li>
</ul>
<p>当我们在 _all 域查询 2014它匹配所有的12条推文因为它们都含有 2014 </p>
<pre><code class="language-bash">GET /_search?q=2014 # 12 results
</code></pre>
<p>当我们在 _all 域查询 2014-09-15它首先分析查询字符串产生匹配 2014 09 或 15 中 任意 词条的查询。这也会匹配所有12条推文因为它们都含有 2014 </p>
<pre><code class="language-bash">GET /_search?q=2014-09-15 # 12 results !
</code></pre>
<p>当我们在 date 域查询 2014-09-15它寻找 精确 日期,只找到一个推文:</p>
<pre><code class="language-bash">GET /_search?q=date:2014-09-15 # 1 result
</code></pre>
<p>当我们在 date 域查询 2014它找不到任何文档因为没有文档含有这个精确日志</p>
<pre><code class="language-bash">GET /_search?q=date:2014 # 0 results !
</code></pre>
<h2>参考文章</h2>
<p>https://new.qq.com/omn/20210320/20210320A01XHF00.html</p>
<p>https://juejin.cn/post/6844903473666867208</p>
<p>http://lucene.apache.org/core/7_2_1/core/org/apache/lucene/codecs/lucene70/package-summary.html#package.description</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/ElasticSearch知识体系详解/13 原理从图解构筑对ES原理的初步认知.md">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/ElasticSearch知识体系详解/15 原理ES原理之索引文档流程详解.md">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70996faa39713d60","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>