<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Sherwin.Wei</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <icon>https://javai.tech/images/javai-avatar.png</icon>
  <id>https://javai.tech/</id>
  <link href="https://javai.tech/" rel="alternate"/>
  <link href="https://javai.tech/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, Sherwin.Wei</rights>
  <subtitle>java与ai结合一定会更强更远！</subtitle>
  <title>javai - java与ai</title>
  <updated>2026-08-26T17:18:12.214Z</updated>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="个人站" scheme="https://javai.tech/categories/%E4%B8%AA%E4%BA%BA%E7%AB%99/"/>
    <category term="SEO" scheme="https://javai.tech/categories/%E4%B8%AA%E4%BA%BA%E7%AB%99/SEO/"/>
    <category term="SEO" scheme="https://javai.tech/tags/SEO/"/>
    <category term="Hexo" scheme="https://javai.tech/tags/Hexo/"/>
    <category term="Redefine" scheme="https://javai.tech/tags/Redefine/"/>
    <category term="改造复盘" scheme="https://javai.tech/tags/%E6%94%B9%E9%80%A0%E5%A4%8D%E7%9B%98/"/>
    <category term="个人技术站" scheme="https://javai.tech/tags/%E4%B8%AA%E4%BA%BA%E6%8A%80%E6%9C%AF%E7%AB%99/"/>
    <content>
      <![CDATA[<h1 id="自己站-SEO-改造复盘：从默认主题到完整元数据"><a href="#自己站-SEO-改造复盘：从默认主题到完整元数据" class="headerlink" title="自己站 SEO 改造复盘：从默认主题到完整元数据"></a>自己站 SEO 改造复盘：从默认主题到完整元数据</h1><blockquote><p>自己的 javai.tech 站，最近半年没更新。偶然打开 View Source 一看，差点没晕过去——<br>og:title 是 “Hexo”，author 是 “John Doe”，连个 description 都没有。<br>搜索引擎大概也懵了：<strong>这是谁的站？</strong> 本文复盘整个改造过程。</p></blockquote><h2 id="一、为什么突然想修？"><a href="#一、为什么突然想修？" class="headerlink" title="一、为什么突然想修？"></a>一、为什么突然想修？</h2><p>事情是这样的：</p><p>最近一直在做 AI 相关项目，朋友圈里也开始有人搜「javai」「Sherwin Wei Java」想找到我。结果我跟朋友开玩笑说「你搜 javai.tech 看看」，他搜了，说：</p><blockquote><p>「搜出来一堆东西，但都是 Hexo 主题相关的内容，不像你的站啊？」</p></blockquote><p>我打开浏览器，登录百度站长、Google Search Console，再 <code>curl https://javai.tech</code>，看返回的 HTML。</p><p>然后愣住了。</p><hr><h2 id="二、诊断：体检报告"><a href="#二、诊断：体检报告" class="headerlink" title="二、诊断：体检报告"></a>二、诊断：体检报告</h2><p>下面这段，是我跑 <code>curl https://javai.tech | grep -E &#39;og:|description|author&#39;</code> 抓出来的真实数据：</p><div class="highlight-container" data-rel="Html"><figure class="iseeu highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;keywords&quot;</span> <span class="attr">content</span>=<span class="string">&quot;Hexo Theme Redefine&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;author&quot;</span> <span class="attr">content</span>=<span class="string">&quot;John Doe&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">meta</span> <span class="attr">property</span>=<span class="string">&quot;og:title&quot;</span> <span class="attr">content</span>=<span class="string">&quot;Hexo&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">meta</span> <span class="attr">property</span>=<span class="string">&quot;og:site_name&quot;</span> <span class="attr">content</span>=<span class="string">&quot;Hexo&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">meta</span> <span class="attr">property</span>=<span class="string">&quot;og:locale&quot;</span> <span class="attr">content</span>=<span class="string">&quot;en_US&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">&quot;canonical&quot;</span> <span class="attr">href</span>=<span class="string">&quot;http://javai.tech/&quot;</span>&gt;</span></span><br></pre></td></tr></table></figure></div><p>看见没？六个 meta，全错。</p><ul><li><code>keywords</code> 是主题名字「Hexo Theme Redefine」</li><li><code>author</code> 是 Hexo 默认占位的 <strong>「John Doe」</strong></li><li><code>og:title</code> 直接就是「Hexo」两个字</li><li><code>og:locale</code> 是 <code>en_US</code>，但内容全是中文</li><li><code>canonical</code> 还是 <code>http://</code>，没用 https</li></ul><p>更离谱的是 404 页面。我访问 <code>/xxx</code>（不存在的路径），打开 View Source，作者也是 John Doe。也就是说，搜索引擎每抓到一个不存在的链接，都以为这是某个叫 John Doe 的英文博客。</p><hr><h2 id="三、问题清单：哪些是真正的硬伤"><a href="#三、问题清单：哪些是真正的硬伤" class="headerlink" title="三、问题清单：哪些是真正的硬伤"></a>三、问题清单：哪些是真正的硬伤</h2><p>我把这些分了三档：</p><h3 id="🔴-P0：必须立刻修（不改搜索引擎看不懂你是谁）"><a href="#🔴-P0：必须立刻修（不改搜索引擎看不懂你是谁）" class="headerlink" title="🔴 P0：必须立刻修（不改搜索引擎看不懂你是谁）"></a>🔴 P0：必须立刻修（不改搜索引擎看不懂你是谁）</h3><table><thead><tr><th>问题</th><th>现状</th><th>修复</th></tr></thead><tbody><tr><td><code>og:title</code></td><td>“Hexo”</td><td>“javai - java与ai”</td></tr><tr><td><code>og:site_name</code></td><td>“Hexo”</td><td>“javai”</td></tr><tr><td><code>meta author</code></td><td>“John Doe”</td><td>“Sherwin.Wei”</td></tr><tr><td><code>meta keywords</code></td><td>“Hexo Theme Redefine”</td><td>真实关键词</td></tr><tr><td><code>meta description</code></td><td><strong>缺失</strong></td><td>站点描述</td></tr><tr><td><code>og:image</code></td><td><strong>缺失</strong></td><td>分享卡片图</td></tr><tr><td><code>canonical</code></td><td>http</td><td>https</td></tr><tr><td><code>&lt;html lang&gt;</code></td><td>“en”</td><td>“zh-CN”</td></tr></tbody></table><h3 id="🟡-P1：能加就加（影响收录和订阅）"><a href="#🟡-P1：能加就加（影响收录和订阅）" class="headerlink" title="🟡 P1：能加就加（影响收录和订阅）"></a>🟡 P1：能加就加（影响收录和订阅）</h3><ul><li>没有 <code>sitemap.xml</code>，搜索引擎不知道你有多少页面</li><li>没有 <code>robots.txt</code>，抓取规则没有声明</li><li>没有 RSS &#x2F; Atom feed，想订阅的用户没路径</li><li>没有站内搜索，<code>Ctrl+K</code> 啥也没反应</li></ul><h3 id="🟢-P2：长期才能见效"><a href="#🟢-P2：长期才能见效" class="headerlink" title="🟢 P2：长期才能见效"></a>🟢 P2：长期才能见效</h3><ul><li>Google Analytics 没接，访问数据是黑盒</li><li>百度统计没接，国内访问数据不准确</li><li>分享到微信&#x2F;微博没图没描述，传播效果差</li></ul><hr><h2 id="四、修复实施"><a href="#四、修复实施" class="headerlink" title="四、修复实施"></a>四、修复实施</h2><h3 id="第一刀：Hexo-站点的-config-yml"><a href="#第一刀：Hexo-站点的-config-yml" class="headerlink" title="第一刀：Hexo 站点的 _config.yml"></a>第一刀：Hexo 站点的 <code>_config.yml</code></h3><p>这是所有问题的根源。打开一看，全是默认占位：</p><div class="highlight-container" data-rel="Yaml"><figure class="iseeu highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">title:</span> <span class="string">Hexo</span></span><br><span class="line"><span class="attr">description:</span> <span class="string">&#x27;&#x27;</span></span><br><span class="line"><span class="attr">keywords:</span></span><br><span class="line"><span class="attr">author:</span> <span class="string">John</span> <span class="string">Doe</span></span><br><span class="line"><span class="attr">language:</span> <span class="string">en</span></span><br><span class="line"><span class="attr">timezone:</span> <span class="string">&#x27;&#x27;</span></span><br><span class="line"><span class="attr">url:</span> <span class="string">http://example.com</span>    <span class="comment"># ← 这里是 example.com，不是 javai.tech</span></span><br></pre></td></tr></table></figure></div><p>这一段不改，其他都白搭。改成：</p><div class="highlight-container" data-rel="Yaml"><figure class="iseeu highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">title:</span> <span class="string">javai</span> <span class="bullet">-</span> <span class="string">java与ai</span></span><br><span class="line"><span class="attr">subtitle:</span> <span class="string">java与ai结合一定会更强更远！</span></span><br><span class="line"><span class="attr">description:</span> <span class="string">&#x27;Sherwin.Wei（魏远标）个人技术站，分享 Java/AI 实战、系统设计面试、前后端架构、国学智慧与现代技术融合。13 年经验，曾就职于美的、亿迅、华为。&#x27;</span></span><br><span class="line"><span class="attr">keywords:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">javai</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">java与ai</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">Sherwin.Wei</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">魏远标</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">Java</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">AI</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">系统设计</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">后端开发</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">面试题</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">Elasticsearch</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">Spring</span> <span class="string">Boot</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">AI定制开发</span></span><br><span class="line"><span class="attr">author:</span> <span class="string">Sherwin.Wei</span></span><br><span class="line"><span class="attr">language:</span> <span class="string">zh-CN</span></span><br><span class="line"><span class="attr">timezone:</span> <span class="string">Asia/Shanghai</span></span><br><span class="line"><span class="attr">url:</span> <span class="string">https://javai.tech</span></span><br></pre></td></tr></table></figure></div><blockquote><p>⚠️ 关键点：<code>url</code> 一定要写对。Hexo 的 canonical、sitemap、feed、og:url 全靠这个字段。一字之差，搜索引擎就不认你。</p></blockquote><h3 id="第二刀：装三个包"><a href="#第二刀：装三个包" class="headerlink" title="第二刀：装三个包"></a>第二刀：装三个包</h3><p>默认装的只有 archive、category、tag、index 这几个 generator，<strong>没装 sitemap、feed、search</strong>。</p><div class="highlight-container" data-rel="Bash"><figure class="iseeu highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-generator-sitemap hexo-generator-feed hexo-generator-search --save</span><br></pre></td></tr></table></figure></div><p>装完在 <code>_config.yml</code> 加：</p><div class="highlight-container" data-rel="Yaml"><figure class="iseeu highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">sitemap:</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">sitemap.xml</span></span><br><span class="line">  <span class="attr">url:</span> <span class="string">https://javai.tech</span>        <span class="comment"># 注意：也要写对 url，否则 sitemap 全是 http</span></span><br><span class="line"></span><br><span class="line"><span class="attr">feed:</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">atom</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">atom.xml</span></span><br><span class="line">  <span class="attr">limit:</span> <span class="number">20</span></span><br><span class="line"></span><br><span class="line"><span class="attr">search:</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">search.json</span></span><br><span class="line">  <span class="attr">field:</span> <span class="string">post</span></span><br><span class="line">  <span class="attr">format:</span> <span class="string">html</span></span><br><span class="line">  <span class="attr">limit:</span> <span class="number">10000</span></span><br></pre></td></tr></table></figure></div><h3 id="第三刀：补-OG-图"><a href="#第三刀：补-OG-图" class="headerlink" title="第三刀：补 OG 图"></a>第三刀：补 OG 图</h3><p><code>og:image</code> 是分享到微信&#x2F;微博&#x2F;LinkedIn&#x2F;Twitter 时的封面图。没有它，分享卡片就是个白板。</p><p>我用 Python + Pillow 临时画了一张（1200×600）：</p><div class="highlight-container" data-rel="Python"><figure class="iseeu highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> Image, ImageDraw, ImageFont</span><br><span class="line"></span><br><span class="line">W, H = <span class="number">1200</span>, <span class="number">630</span></span><br><span class="line">img = Image.new(<span class="string">&#x27;RGB&#x27;</span>, (W, H), (<span class="number">163</span>, <span class="number">31</span>, <span class="number">52</span>))  <span class="comment"># #A31F34 品牌色</span></span><br><span class="line">draw = ImageDraw.Draw(img)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 渐变背景</span></span><br><span class="line"><span class="keyword">for</span> y <span class="keyword">in</span> <span class="built_in">range</span>(H):</span><br><span class="line">    ratio = y / H</span><br><span class="line">    draw.line([(<span class="number">0</span>, y), (W, y)],</span><br><span class="line">              fill=(<span class="number">163</span> - <span class="number">25</span>*ratio, <span class="number">31</span> + <span class="number">5</span>*ratio, <span class="number">52</span> + <span class="number">10</span>*ratio))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 主标题</span></span><br><span class="line">title_font = ImageFont.truetype(<span class="string">&#x27;/System/Library/Fonts/PingFang.ttc&#x27;</span>, <span class="number">200</span>)</span><br><span class="line">draw.text(((W - <span class="number">480</span>) / <span class="number">2</span>, <span class="number">140</span>), <span class="string">&#x27;javai&#x27;</span>, fill=<span class="string">&#x27;white&#x27;</span>, font=title_font)</span><br><span class="line">draw.text(((W - <span class="number">240</span>) / <span class="number">2</span>, <span class="number">380</span>), <span class="string">&#x27;java与ai&#x27;</span>, fill=(<span class="number">255</span>, <span class="number">240</span>, <span class="number">230</span>),</span><br><span class="line">          font=ImageFont.truetype(<span class="string">&#x27;/System/Library/Fonts/PingFang.ttc&#x27;</span>, <span class="number">56</span>))</span><br><span class="line">draw.text(((W - <span class="number">360</span>) / <span class="number">2</span>, <span class="number">500</span>), <span class="string">&#x27;Sherwin.Wei · 个人技术站&#x27;</span>,</span><br><span class="line">          fill=(<span class="number">255</span>, <span class="number">230</span>, <span class="number">220</span>),</span><br><span class="line">          font=ImageFont.truetype(<span class="string">&#x27;/System/Library/Fonts/PingFang.ttc&#x27;</span>, <span class="number">26</span>))</span><br><span class="line"></span><br><span class="line">img.save(<span class="string">&#x27;source/images/javai-og-cover.png&#x27;</span>, <span class="string">&#x27;PNG&#x27;</span>, optimize=<span class="literal">True</span>)</span><br></pre></td></tr></table></figure></div><p>5 分钟搞定。专业设计师看不上，但比自己强太多。</p><h3 id="第四刀：head-注入"><a href="#第四刀：head-注入" class="headerlink" title="第四刀：head 注入"></a>第四刀：head 注入</h3><p>Redefine 主题用的是 <code>inject.head</code> 机制（不是 <code>source/_data/head.json</code>，那个我没试成功）。在 <code>_config.redefine.yml</code> 加：</p><div class="highlight-container" data-rel="Yaml"><figure class="iseeu highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;&lt;meta property=&quot;og:image&quot; content=&quot;https://javai.tech/images/javai-og-cover.png&quot;&gt;&#x27;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;&lt;meta property=&quot;og:image:width&quot; content=&quot;1200&quot;&gt;&#x27;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;&lt;meta property=&quot;og:image:height&quot; content=&quot;630&quot;&gt;&#x27;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;&lt;meta name=&quot;twitter:card&quot; content=&quot;summary_large_image&quot;&gt;&#x27;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;&lt;meta name=&quot;twitter:title&quot; content=&quot;javai - java与ai&quot;&gt;&#x27;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;&lt;meta name=&quot;twitter:image&quot; content=&quot;https://javai.tech/images/javai-og-cover.png&quot;&gt;&#x27;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&#x27;&lt;link rel=&quot;alternate&quot; type=&quot;application/atom+xml&quot; title=&quot;javai - java与ai&quot; href=&quot;https://javai.tech/atom.xml&quot;&gt;&#x27;</span></span><br><span class="line">  <span class="attr">footer:</span> []</span><br></pre></td></tr></table></figure></div><blockquote><p>这个机制的好处是<strong>改配置不改主题</strong>，主题升级不会被覆盖。</p></blockquote><h3 id="第五刀：robots-txt"><a href="#第五刀：robots-txt" class="headerlink" title="第五刀：robots.txt"></a>第五刀：robots.txt</h3><p>放在 <code>source/robots.txt</code>：</p><div class="highlight-container" data-rel="Plaintext"><figure class="iseeu highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">User-agent: *</span><br><span class="line">Allow: /</span><br><span class="line"></span><br><span class="line">Disallow: /404.html</span><br><span class="line">Disallow: /search/</span><br><span class="line"></span><br><span class="line">Sitemap: https://javai.tech/sitemap.xml</span><br><span class="line">Sitemap: https://javai.tech/atom.xml</span><br></pre></td></tr></table></figure></div><p>注意：Sitemap 一定要写完整 URL，不要写相对路径。</p><h3 id="第六刀：导航-站内搜索"><a href="#第六刀：导航-站内搜索" class="headerlink" title="第六刀：导航 + 站内搜索"></a>第六刀：导航 + 站内搜索</h3><p>在 <code>_config.redefine.yml</code> 的 navbar 加 search：</p><div class="highlight-container" data-rel="Yaml"><figure class="iseeu highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">navbar:</span></span><br><span class="line">  <span class="attr">links:</span></span><br><span class="line">    <span class="string">面试:</span></span><br><span class="line">      <span class="attr">path:</span> <span class="string">/interview/</span></span><br><span class="line">    <span class="string">服务:</span>                  <span class="comment"># 新增</span></span><br><span class="line">      <span class="attr">path:</span> <span class="string">/services/</span></span><br><span class="line">    <span class="attr">chat:</span></span><br><span class="line">      <span class="attr">path:</span> <span class="string">/chat</span></span><br><span class="line">    <span class="comment"># ... 其他保持不变</span></span><br><span class="line">  <span class="attr">search:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span>            <span class="comment"># 启用站内搜索</span></span><br><span class="line">    <span class="attr">preload:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure></div><hr><h2 id="五、验收"><a href="#五、验收" class="headerlink" title="五、验收"></a>五、验收</h2><p>部署前先本地 <code>hexo clean &amp;&amp; hexo generate</code>，看会不会报错。没问题了再 <code>hexo deploy</code>。</p><p>部署完等 2-5 分钟，跑几个 curl 验证：</p><div class="highlight-container" data-rel="Bash"><figure class="iseeu highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 检查 meta 修复</span></span><br><span class="line">curl -s https://javai.tech | grep -E <span class="string">&#x27;og:title|og:image|author&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 期望：</span></span><br><span class="line"><span class="comment"># &lt;meta name=&quot;author&quot; content=&quot;Sherwin.Wei&quot;&gt;</span></span><br><span class="line"><span class="comment"># &lt;meta property=&quot;og:title&quot; content=&quot;javai - java与ai&quot;&gt;</span></span><br><span class="line"><span class="comment"># &lt;meta property=&quot;og:image&quot; content=&quot;https://javai.tech/images/javai-og-cover.png&quot;&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 检查 sitemap URL 全部 https</span></span><br><span class="line">curl -s https://javai.tech/sitemap.xml | grep -oE <span class="string">&#x27;javai\.tech[^&lt;]+&#x27;</span> | <span class="built_in">head</span> -3</span><br><span class="line"></span><br><span class="line"><span class="comment"># 期望：</span></span><br><span class="line"><span class="comment"># https://javai.tech/aboutme/index.html</span></span><br><span class="line"><span class="comment"># https://javai.tech/services/index.html</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 检查 atom.xml 正常</span></span><br><span class="line">curl -s https://javai.tech/atom.xml | <span class="built_in">head</span> -5</span><br><span class="line"><span class="comment"># 期望：&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;...</span></span><br></pre></td></tr></table></figure></div><p>我自己跑下来，生成 705 个文件、sitemap 包含 473 个 URL，全部 https。</p><hr><h2 id="六、经验总结"><a href="#六、经验总结" class="headerlink" title="六、经验总结"></a>六、经验总结</h2><h3 id="1-默认值的陷阱"><a href="#1-默认值的陷阱" class="headerlink" title="1. 默认值的陷阱"></a>1. 默认值的陷阱</h3><p>Hexo 的模板里 <code>title: Hexo</code>、<code>author: John Doe</code>、<code>url: http://example.com</code>，新手很容易被「主题配了就行」骗过去。<strong>主题配置 ≠ 站点配置</strong>。主题只是换了外观，HTML head 里的 og&#x2F;author&#x2F;canonical 这些是 Hexo 自己吐的，看的是站点 <code>_config.yml</code>。</p><h3 id="2-第一时间验证部署后的-HTML"><a href="#2-第一时间验证部署后的-HTML" class="headerlink" title="2. 第一时间验证部署后的 HTML"></a>2. 第一时间验证部署后的 HTML</h3><p>每次部署完，第一件事应该是 <code>curl https://yoursite.com | head -50</code>，而不是打开浏览器看页面。</p><ul><li>浏览器只能看到视觉效果</li><li>搜索引擎只看 HTML 源码</li><li>分享卡片生成器只看 og:image、og:title、og:description</li></ul><p>我这次能发现问题，就是 <code>curl</code> 救了我。</p><h3 id="3-sitemap-的-url-必须显式声明"><a href="#3-sitemap-的-url-必须显式声明" class="headerlink" title="3. sitemap 的 url 必须显式声明"></a>3. sitemap 的 url 必须显式声明</h3><p>hexo-generator-sitemap 默认用 <code>site.url</code> 生成，但如果 <code>site.url</code> 写错了（比如写成 http），整个 sitemap 就是 http 版本。</p><ul><li>Google 会按 http 收录</li><li>HSTS 升级后又会被认为是迁移</li><li>反复折腾</li></ul><p>所以在配置里<strong>额外</strong>写一遍 <code>sitemap.url</code> 是值得的。</p><h3 id="4-别相信「主题文档」说一切正常"><a href="#4-别相信「主题文档」说一切正常" class="headerlink" title="4. 别相信「主题文档」说一切正常"></a>4. 别相信「主题文档」说一切正常</h3><p>Redefine 主题的文档看着很全，但默认配置下：</p><ul><li>search 是关的</li><li>GA 是关的</li><li>social_links 是关的</li><li>feed 是关的</li></ul><p><strong>默认 + 不改 &#x3D; 啥也没有</strong>。这点不如早期的 Next 主题，至少 Next 默认开 search 和 RSS。</p><h3 id="5-中英文站的-lang-配置"><a href="#5-中英文站的-lang-配置" class="headerlink" title="5. 中英文站的 lang 配置"></a>5. 中英文站的 lang 配置</h3><p><code>&lt;html lang=&quot;en&quot;&gt;</code> 看起来「无害」，但百度会直接降低权重。<br>中文内容必须 <code>lang=&quot;zh-CN&quot;</code>。</p><h3 id="6-description-千万别空着"><a href="#6-description-千万别空着" class="headerlink" title="6. description 千万别空着"></a>6. description 千万别空着</h3><p>搜索引擎在搜索结果里展示的两行摘要，就是 description。没填的话，搜索引擎会从正文里截一段，经常截得莫名其妙（特别是代码块）。</p><p>我这次给的 description：</p><blockquote><p>Sherwin.Wei（魏远标）个人技术站，分享 Java&#x2F;AI 实战、系统设计面试、前后端架构、国学智慧与现代技术融合。13 年经验，曾就职于美的、亿迅、华为。</p></blockquote><p>覆盖了品牌（Sherwin.Wei）+ 关键词（Java、AI、系统设计）+ 差异化（国学）+ 信任锚（13 年经验、大厂）。</p><h3 id="7-OG-图是社交传播的入口"><a href="#7-OG-图是社交传播的入口" class="headerlink" title="7. OG 图是社交传播的入口"></a>7. OG 图是社交传播的入口</h3><p>我自己测过，分享 javai.tech 之前，微信&#x2F;微博卡片就一个标题加一行小字。<br>之后，1200×630 大图、标题、描述、域名全有。<br><strong>同样的内容，传播效率至少差 3 倍。</strong></p><hr><h2 id="七、下一步"><a href="#七、下一步" class="headerlink" title="七、下一步"></a>七、下一步</h2><p>SEO 修完了，但站还得「活」起来。我给自己定了三条线：</p><ol><li><strong>月更 8-10 篇</strong>：四个系列轮转（面试题深挖、AI 实战、国学智医五行、案例复盘）</li><li><strong>第一个月提交百度站长 + Google Search Console</strong>：让搜索引擎主动来抓</li><li><strong>接入 GA + 百度统计</strong>：知道流量从哪来、用户看什么</li></ol><p>如果一个月后流量没起来，再来写下一篇复盘：《SEO 修完了，为什么流量还是没起色？》</p><hr><h2 id="附录：可复制的-SEO-自检清单"><a href="#附录：可复制的-SEO-自检清单" class="headerlink" title="附录：可复制的 SEO 自检清单"></a>附录：可复制的 SEO 自检清单</h2><p>部署后跑一遍，5 分钟搞定：</p><div class="highlight-container" data-rel="Bash"><figure class="iseeu highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">curl -s https://yoursite.com | grep -E <span class="string">&#x27;og:title|og:image|description|author|canonical&#x27;</span> | <span class="built_in">sort</span> -u</span><br><span class="line"></span><br><span class="line">curl -s https://yoursite.com/sitemap.xml | <span class="built_in">head</span> -3</span><br><span class="line">curl -s https://yoursite.com/atom.xml | <span class="built_in">head</span> -3</span><br><span class="line">curl -s https://yoursite.com/robots.txt</span><br><span class="line">curl -sI https://yoursite.com | grep -i <span class="string">&#x27;strict-transport\|location&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 找有没有漏改的「Hexo」「John Doe」「example.com」</span></span><br><span class="line">curl -s https://yoursite.com | grep -iE <span class="string">&#x27;hexo|john doe|example\.com&#x27;</span></span><br></pre></td></tr></table></figure></div><p>如果第三步还有任何输出，说明还没改干净。</p><hr><blockquote><p><strong>给自己的话</strong>：<br>一个写代码的人，连自己的站都懒得维护好，是说不过去的。<br>这次改造花了半天，但下次别人搜到我时，第一眼看到的不再是「Hexo 默认主题」，<br>而是一个有名字、有故事、有内容的站。这就够了。</p></blockquote>]]>
    </content>
    <id>https://javai.tech/2026/08/26/%E4%B8%AA%E4%BA%BA%E7%AB%99/2026-08-26-%E8%87%AA%E5%B7%B1%E7%AB%99SEO%E6%94%B9%E9%80%A0%E5%A4%8D%E7%9B%98%EF%BC%9A%E4%BB%8E%E9%BB%98%E8%AE%A4%E4%B8%BB%E9%A2%98%E5%88%B0%E5%AE%8C%E6%95%B4%E5%85%83%E6%95%B0%E6%8D%AE/</id>
    <link href="https://javai.tech/2026/08/26/%E4%B8%AA%E4%BA%BA%E7%AB%99/2026-08-26-%E8%87%AA%E5%B7%B1%E7%AB%99SEO%E6%94%B9%E9%80%A0%E5%A4%8D%E7%9B%98%EF%BC%9A%E4%BB%8E%E9%BB%98%E8%AE%A4%E4%B8%BB%E9%A2%98%E5%88%B0%E5%AE%8C%E6%95%B4%E5%85%83%E6%95%B0%E6%8D%AE/"/>
    <published>2026-08-26T15:50:00.000Z</published>
    <summary>自己的 javai.tech 半年没更新，被搜索引擎当成「默认 Hexo 主题」。本文复盘从发现问题到完整修复的全过程，给其他个人站长一份可抄作业的清单。</summary>
    <title>自己站 SEO 改造复盘：从默认主题到完整元数据</title>
    <updated>2026-08-26T17:18:12.214Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch API" scheme="https://javai.tech/tags/Elasticsearch-API/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-中-Explore-API-的功能和应用场景是什么？"><a href="#Elasticsearch-中-Explore-API-的功能和应用场景是什么？" class="headerlink" title="Elasticsearch 中 Explore API 的功能和应用场景是什么？"></a>Elasticsearch 中 Explore API 的功能和应用场景是什么？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 中的 Explore API，主要功能是帮助开发者和用户对数据进行探索性分析。它允许执行复杂的查询和聚合操作，从而提供关于数据的高层次洞察。Explore API 为用户提供了一种灵活且高效的方法来检索和处理存储在 Elasticsearch 中的大规模数据。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>Explore API 是 Elasticsearch 的核心组成部分，它提供了多种功能和应用场景，使其在大数据分析和搜索引擎优化中非常重要。以下是一些具体的扩展知识点：</p><p>1）<strong>基础查询</strong><br>Explore API 可以执行简单到复杂的搜索查询，例如匹配查询、布尔查询、范围查询等。这些查询允许用户根据特定的条件过滤数据，获取所需的信息。</p><p>2）<strong>聚合操作</strong><br>聚合功能使用户能够执行统计分析，例如计算平均值、最大值、最小值、总和以及分组统计等。这对于数据分析和报告生成非常有用。例如，电子商务网站可以使用聚合操作来统计销售数据，从而优化库存和营销策略。</p><p>3）<strong>全文搜索</strong><br>Explore API 拥有强大的全文搜索能力，这使得它在实现搜索功能时非常高效。通过分词、打分、相关度排序等技术，用户可以精准地获取搜索结果。这在内容管理系统（CMS）和博客等应用中非常常见。</p><p>4）<strong>数据过滤和排序</strong><br>用户可以使用 Explore API 对数据进行细粒度的过滤和排序，满足特定的业务需求。例如，在日志分析场景中，可以根据时间、级别等不同维度来筛选和排序日志数据。</p><p>5）<strong>地理空间查询</strong><br>对于包含地理位置信息的数据，Explore API 还支持地理搜索和聚合操作。可以进行地理范围查询、地理距离排序等。这在地图服务、位置推荐等应用场景中非常有用。</p><p>6）<strong>多语言支持</strong><br>由于 Elasticsearch 支持多种语言的分词器和分析器，Explore API 也能够处理不同语言的数据搜索和分析，这使得其在国际化应用中具有很大优势。</p><p>7）<strong>扩展性和实时性</strong><br>Elasticsearch 和它的 Explore API 天然支持扩展性和高吞吐量，可以处理海量数据。而且其近实时（Near Real-Time, NRT）特性使得它能够迅速响应数据写入和更新操作。</p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5769.Elasticsearch%E4%B8%ADExploreAPI%E7%9A%84%E5%8A%9F%E8%83%BD%E5%92%8C%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5769.Elasticsearch%E4%B8%ADExploreAPI%E7%9A%84%E5%8A%9F%E8%83%BD%E5%92%8C%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-中-Explore-API-的功能和应用场景是什么？"><a href="#Elasticsearch-中-Explore-API-的功能和应用场景是什么？" class="headerlink"]]>
    </summary>
    <title>Elasticsearch 中 Explore API 的功能和应用场景是什么？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch特性" scheme="https://javai.tech/tags/Elasticsearch%E7%89%B9%E6%80%A7/"/>
    <content>
      <![CDATA[<h1 id="当前稳定版本的-Elasticsearch-具备哪些核心特性和改进？"><a href="#当前稳定版本的-Elasticsearch-具备哪些核心特性和改进？" class="headerlink" title="当前稳定版本的 Elasticsearch 具备哪些核心特性和改进？"></a>当前稳定版本的 Elasticsearch 具备哪些核心特性和改进？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 是一个开源的搜索和分析引擎，具备高效、分布式和实时的特点。当前稳定版本的 Elasticsearch 具备以下核心特性和改进：</p><p>1）<strong>索引和搜索</strong>：Elasticsearch 提供了强大的全文搜索能力，支持各种类型的数据索引，从结构化数据到非结构化数据。<br>2）<strong>分布式架构</strong>：支持分布式计算，可以轻松扩展至数百个节点并处理 PB 级的数据。<br>3）<strong>高可用性</strong>：通过分片和副本机制，实现数据的高可用性和容错性。<br>4）<strong>聚合功能</strong>：支持复杂的数据分析和聚合操作，满足各种大数据分析需求。<br>5）<strong>近实时搜索</strong>：数据在写入后几乎可以立刻进行搜索，这是由于其高效的刷新机制。<br>6）<strong>安全性</strong>：内置了丰富的安全特性，包括 X-Pack 插件，提供加密通讯、用户认证和授权等安全控制。<br>7）<strong>机器学习</strong>：内置的机器学习功能，使用户能够进行异常检测、数据预测等高级数据分析。<br>8）<strong>Kibana 集成</strong>：与 Kibana 无缝集成，提供数据可视化、监控和管理工具。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>Elasticsearch 的核心特性和最新改进让它在许多领域有广泛应用。</p><p>1）<strong>索引和搜索</strong>：</p><ul><li>Elasticsearch 支持多种查询类型，包括全文搜索、结构化搜索（比如 term 查询）和组合查询（Bool 查询）。</li><li>它还支持正则表达式和模糊搜索，非常适合复杂的搜索需求。</li></ul><p>2）<strong>分布式架构</strong>： </p><ul><li>Elasticsearch 使用文档（Document）存储数据，文档再存储在索引中，每个索引里面包含多个分片（Shard）。分片机制使得索引可以分布在多个节点，提高了数据处理能力和容错性。</li></ul><p>3）<strong>高可用性</strong>：</p><ul><li>副本机制确保数据不会因为节点故障而丢失。每个分片都有一个或多个副本，分布在不同的物理节点上。</li></ul><p>4）<strong>聚合功能</strong>：</p><ul><li>提供多种聚合操作，比如 Avg、Sum、Min、Max 等，用于统计分析。此外，Elasticsearch 支持桶（Bucket）和度量（Metric）的组合，能进行更复杂的数据分析。</li></ul><p>5）<strong>近实时搜索</strong>：</p><ul><li>数据写入（Indexing）后会快速刷新到搜索系统中，这意味着数据几乎是实时可搜索的，对那些需要实时分析的应用非常有用。</li></ul><p>6）<strong>安全性</strong>：</p><ul><li>X-Pack 是官方提供的安全和扩展包，包括监控、告警、报告等功能，还提供更细粒度的访问控制和数据加密。</li></ul><p>7）<strong>机器学习</strong>：</p><ul><li>内置的机器学习模块能自动适应数据变化，进行异常检测。例如，可以利用机器学习分析访问日志，自动发现异常行为进行告警。</li></ul><p>8）<strong>Kibana 集成</strong>：</p><ul><li>Kibana 是 Elasticsearch 的可视化工具，可以用来创建各种可视化报表和仪表盘，直观展示数据分析结果，还提供交互式的界面进行数据探索。</li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5768.%E5%BD%93%E5%89%8D%E7%A8%B3%E5%AE%9A%E7%89%88%E6%9C%AC%E7%9A%84Elasticsearch%E5%85%B7%E5%A4%87%E5%93%AA%E4%BA%9B%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7%E5%92%8C%E6%94%B9%E8%BF%9B%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5768.%E5%BD%93%E5%89%8D%E7%A8%B3%E5%AE%9A%E7%89%88%E6%9C%AC%E7%9A%84Elasticsearch%E5%85%B7%E5%A4%87%E5%93%AA%E4%BA%9B%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7%E5%92%8C%E6%94%B9%E8%BF%9B%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="当前稳定版本的-Elasticsearch-具备哪些核心特性和改进？"><a href="#当前稳定版本的-Elasticsearch-具备哪些核心特性和改进？" class="headerlink" title="当前稳定版本的 Elasticsearch]]>
    </summary>
    <title>当前稳定版本的 Elasticsearch 具备哪些核心特性和改进？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Solr" scheme="https://javai.tech/tags/Solr/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-与-Solr-有哪些区别？"><a href="#Elasticsearch-与-Solr-有哪些区别？" class="headerlink" title="Elasticsearch 与 Solr 有哪些区别？"></a>Elasticsearch 与 Solr 有哪些区别？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 和 Solr 都是常用的搜索引擎解决方案，但是它们在架构、数据存储、可扩展性、社区支持和使用体验等多个方面存在显著差异。</p><p>1）架构方面：Elasticsearch 使用的是分布式架构，天然支持分片和副本，适合处理大规模的数据；Solr 是基于 Apache Lucene 的，尽管也支持分布式，但实现起来更复杂一些。</p><p>2）数据存储：Elasticsearch 默认使用 JSON 格式存储数据，这使得它与现代 RESTful API 自然契合；Solr 通常使用 XML 格式存储数据，显得比较传统。</p><p>3）可扩展性：Elasticsearch 具有自动分片和副本管理功能，非常适合分布式环境；Solr 则需要手动配置 Zookeeper 来管理集群，略显麻烦。</p><p>4）社区和支持：Elasticsearch 有着一个非常活跃的社区并且有企业级支持；Solr 也有一个庞大的用户群体，但在社区活跃度上略输一筹。</p><p>5）使用体验：Elasticsearch 的 RESTful API 和 Kibana 的可视化工具非常方便开发者进行数据操作和监控；Solr 则在配置方面需要更多的手工操作，学习曲线稍陡。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>除了以上几点，还有一些细节差异值得一提：</p><p>1）全文搜索方面：由于两者都基于 Lucene，所以它们在全文搜索的核心功能上大致相同。然而，Elasticsearch 包含了许多内置的相关功能，例如自动补全、拼写纠错等，这些在 Solr 中可能需要额外的插件或自定义。</p><p>2）索引重建：在需要重新索引大量数据时，Elasticsearch 的滚动更新和零停机时间重建机制显得更加成熟；而 Solr 虽然也支持索引重建，但升级和维护过程中需要更多的计划和测试工作。</p><p>3）数据聚合：Elasticsearch 提供了一个非常强大的聚合框架，支持多级聚合和复杂的嵌套聚合；Solr 虽然也支持数据聚合，但在复杂性和灵活性上不如 Elasticsearch 强大。</p><p>4）安装和配置：Elasticsearch 相对更容易安装和配置，其“开箱即用”的特性能让新手更快上手；Solr 的配置稍复杂，尤其是在分布式集群管理方面，这需要开发者更多的经验和理解。</p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5774.Elasticsearch%E4%B8%8ESolr%E6%9C%89%E5%93%AA%E4%BA%9B%E5%8C%BA%E5%88%AB%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5774.Elasticsearch%E4%B8%8ESolr%E6%9C%89%E5%93%AA%E4%BA%9B%E5%8C%BA%E5%88%AB%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-与-Solr-有哪些区别？"><a href="#Elasticsearch-与-Solr-有哪些区别？" class="headerlink" title="Elasticsearch 与 Solr]]>
    </summary>
    <title>Elasticsearch 与 Solr 有哪些区别？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-和关系型数据库有哪些区别？比如数据存储和查询等方面"><a href="#Elasticsearch-和关系型数据库有哪些区别？比如数据存储和查询等方面" class="headerlink" title="Elasticsearch 和关系型数据库有哪些区别？比如数据存储和查询等方面"></a>Elasticsearch 和关系型数据库有哪些区别？比如数据存储和查询等方面</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 是以文档为基础的分布式搜索和分析引擎，而关系型数据库（RDBMS）是一种以表为基础的传统数据库管理系统。它们在数据存储和查询等方面有显著的区别：</p><p>1）<strong>数据存储方式</strong>：</p><ul><li>Elasticsearch 是面向文档的存储，数据以 JSON 文档的形式存储，每个文档是自包含的。</li><li>关系型数据库是基于表格的存储，数据是结构化的，存储在行和列中，具有固定的模式（Schema）。</li></ul><p>2）<strong>查询方式</strong>：</p><ul><li>Elasticsearch 使用查询 DSL（Domain Specific Language），具备强大的全文搜索能力和复杂的查询组合。</li><li>关系型数据库使用 SQL（Structured Query Language），主要用于结构化数据查询和关系操作，支持丰富的聚合和连接操作。</li></ul><p>3）<strong>扩展性</strong>：</p><ul><li>Elasticsearch 天生具有分布式架构，易于水平扩展，能够处理大规模的数据量。</li><li>关系型数据库传统上是垂直扩展，更适合单机模式，尽管有些现代 RDBMS 支持分布式架构，但其扩展性和 Elasticsearch 相比还是较差。</li></ul><p>4）<strong>事务处理</strong>：</p><ul><li>Elasticsearch 较弱，只有近实时性保证，主要侧重于搜索和分析。</li><li>关系型数据库具有强事务处理能力（ACID 属性），用于保证在多操作同时进行时的数据一致性和完整性。</li></ul><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>Elasticsearch 和关系型数据库在内部架构、使用场景和性能上都有各自的特定优势和应用场景。</p><p>1）<strong>使用场景</strong>:</p><ul><li>Elasticsearch 适用于需要快速搜索和分析大规模、非结构化数据的应用场景，如日志分析、实时监控、建议系统和全文搜索等。</li><li>关系型数据库适用于需要强一致性、事务处理能力和复杂查询的场景，如金融系统、库存管理、用户订单处理等。</li></ul><p>2）<strong>性能</strong>:</p><ul><li>Elasticsearch 在全文搜索、模糊匹配、数据分析等方面表现优异，尤其在大数据量下表现突出。</li><li>关系型数据库在复杂的多表关联查询和事务处理上有优势，适合需要精确数据操作的场景。</li></ul><p>3）<strong>集成和生态环境</strong>:</p><ul><li>Elasticsearch 配合 Kibana、Logstash 形成 ELK Stack，是一套非常流行的大数据处理和可视化解决方案。</li><li>关系型数据库有丰富的运维工具和生态支持，包括备份、恢复、监控、优化等方面的工具，都已经经过长时间的验证和使用。</li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5780.Elasticsearch%E5%92%8C%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9C%89%E5%93%AA%E4%BA%9B%E5%8C%BA%E5%88%AB%EF%BC%9F%E6%AF%94%E5%A6%82%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E5%92%8C%E6%9F%A5%E8%AF%A2%E7%AD%89%E6%96%B9%E9%9D%A2/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5780.Elasticsearch%E5%92%8C%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E6%9C%89%E5%93%AA%E4%BA%9B%E5%8C%BA%E5%88%AB%EF%BC%9F%E6%AF%94%E5%A6%82%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E5%92%8C%E6%9F%A5%E8%AF%A2%E7%AD%89%E6%96%B9%E9%9D%A2/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-和关系型数据库有哪些区别？比如数据存储和查询等方面"><a href="#Elasticsearch-和关系型数据库有哪些区别？比如数据存储和查询等方面" class="headerlink" title="Elasticsearch]]>
    </summary>
    <title>Elasticsearch 和关系型数据库有哪些区别？比如数据存储和查询等方面</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="系统设计" scheme="https://javai.tech/tags/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1/"/>
    <content>
      <![CDATA[<h1 id="如何让-Elasticsearch-和数据库（比如-MySQL）的数据保持同步？"><a href="#如何让-Elasticsearch-和数据库（比如-MySQL）的数据保持同步？" class="headerlink" title="如何让 Elasticsearch 和数据库（比如 MySQL）的数据保持同步？"></a>如何让 Elasticsearch 和数据库（比如 MySQL）的数据保持同步？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>要让 Elasticsearch 和数据库（比如 MySQL）的数据保持同步，可以采用以下几种常见方式：</p><p>1）<strong>定时同步：</strong> 定期执行同步任务，将数据库中的最新数据更新到 Elasticsearch 中。可以使用调度任务工具（如 cron、Quartz）来实现。</p><p>2）<strong>实时同步：</strong> 当数据库中的数据发生变化时，立即更新 Elasticsearch。具体实现方式多种多样，例如通过数据库触发器、消息队列（如 Kafka、RabbitMQ）实现。</p><p>3）<strong>增量同步：</strong> 使用变更数据捕获（CDC，Change Data Capture）技术来捕获数据库中的变化，并将这些变化应用到 Elasticsearch。工具如 Debezium 就是一个常用的 CDC 解决方案。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>定时同步：</strong></p><ul><li><strong>实现：</strong> 使用一个调度任务工具来定时执行同步任务，定时批量从数据库中读取新增或更新的数据，然后批量更新到 Elasticsearch。</li><li><strong>优点：</strong> 实现简单，适用于对实时性要求不高的场景。</li><li><strong>缺点：</strong> 存在延迟，与数据库数据之间可能会有时间差。</li></ul><p>2）<strong>实时同步：</strong></p><ul><li><strong>实现：</strong> 数据库发生变化时，通过触发器将变化写入一个中间存储（如消息队列），然后消费者程序从消息队列中读取变化并同步到 Elasticsearch。</li><li><strong>优点：</strong> 数据同步几乎实时，延迟小。</li><li><strong>缺点：</strong> 实现较复杂，需处理分布式系统的一致性和可靠性问题。</li></ul><p>3）<strong>增量同步：</strong></p><ul><li><strong>实现：</strong> 使用 CDC 工具（如 Debezium）监听数据库的更改事件。Debezium 会将这些事件记录到 Kafka 等消息队列中，然后通过消费者程序将这些更改应用到 Elasticsearch。</li><li><strong>优点：</strong> 相较定时同步更实时，且无需修改数据库结构（如添加触发器）。</li><li><strong>缺点：</strong> 需要额外学习和配置 CDC 工具，增加了一些系统复杂性。</li></ul><p>另外，还有一些细节值得考虑：</p><ul><li><strong>数据一致性：</strong> 无论使用哪种同步方法，都要确保在同步过程中数据的一致性，例如保证插入和更新操作顺序。</li><li><strong>错误处理：</strong> 在同步过程中可能会遇到失败的情况，例如网络问题、Elasticsearch 问题，需要设计合适的重试机制。</li><li><strong>性能优化：</strong> 对于大规模数据同步，可能需要考虑批量处理、并发控制等性能优化措施。</li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5790.%E5%A6%82%E4%BD%95%E8%AE%A9Elasticsearch%E5%92%8C%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%88%E6%AF%94%E5%A6%82MySQL%EF%BC%89%E7%9A%84%E6%95%B0%E6%8D%AE%E4%BF%9D%E6%8C%81%E5%90%8C%E6%AD%A5%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5790.%E5%A6%82%E4%BD%95%E8%AE%A9Elasticsearch%E5%92%8C%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%88%E6%AF%94%E5%A6%82MySQL%EF%BC%89%E7%9A%84%E6%95%B0%E6%8D%AE%E4%BF%9D%E6%8C%81%E5%90%8C%E6%AD%A5%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="如何让-Elasticsearch-和数据库（比如-MySQL）的数据保持同步？"><a href="#如何让-Elasticsearch-和数据库（比如-MySQL）的数据保持同步？" class="headerlink" title="如何让]]>
    </summary>
    <title>如何让 Elasticsearch 和数据库（比如 MySQL）的数据保持同步？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch查询" scheme="https://javai.tech/tags/Elasticsearch%E6%9F%A5%E8%AF%A2/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-的-Term、Match-和-Keyword-检索类型有什么区别？"><a href="#Elasticsearch-的-Term、Match-和-Keyword-检索类型有什么区别？" class="headerlink" title="Elasticsearch 的 Term、Match 和 Keyword 检索类型有什么区别？"></a>Elasticsearch 的 Term、Match 和 Keyword 检索类型有什么区别？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Term、Match 和 Keyword 是 Elasticsearch 中非常常用的检索类型，这三者的区别主要在于它们处理查询和数据的方式。</p><p>1）<strong>Term 查询</strong>：Term 查询不会解析查询字符串，而是直接将查询值用于查询。因此，它适用于精确匹配。例如，搜索状态码为 “200” 的文档。</p><p>2）<strong>Match 查询</strong>：Match 查询会将查询字符串进行分词和分析，然后查找与分词后的每个词匹配的文档。因此，它适用于全文搜索。例如，搜索标题包含 “quick brown fox” 的文档。</p><p>3）<strong>Keyword</strong>：Keyword 是一种数据类型，而不是查询类型。它用于存储不会被分词的文本字段，适用于精确匹配和聚合分析。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>Term 查询</strong>：</p><ul><li><strong>数据类型</strong>：适用于 Keyword 类型字段，数字字段和日期字段。</li><li><strong>分析流程</strong>：不进行分词和分析，直接以输入值为准进行查询。</li><li><strong>使用场景</strong>：适用于需要精确匹配的情况，例如状态码、ID、布尔值等场景。</li></ul><p>   示例代码：<br>   <div class="highlight-container" data-rel="Json"><figure class="iseeu highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;term&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;status&quot;</span><span class="punctuation">:</span> <span class="string">&quot;200&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></div></p><p>2）<strong>Match 查询</strong>：</p><ul><li><strong>数据类型</strong>：适用于 Text 类型字段。</li><li><strong>分析流程</strong>：会对查询字符串进行分词和分析。通常情况下，它使用分词器（analyzer）来将查询字符串分成更小的词条。</li><li><strong>使用场景</strong>：适用于全文搜索，例如搜索某篇文章的内容、标题或摘要。</li></ul><p>   示例代码：<br>   <div class="highlight-container" data-rel="Json"><figure class="iseeu highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;match&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;title&quot;</span><span class="punctuation">:</span> <span class="string">&quot;quick brown fox&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></div></p><p>3）<strong>Keyword 数据类型</strong>：</p><ul><li><strong>数据类型</strong>：适用于需要精确匹配的字段。它不会对字段的值进行分词，适合用于 tag、email、URL、身份证号等场景。</li><li><strong>分析流程</strong>：存储时保持原样，不进行分词。</li><li><strong>使用场景</strong>：适用于需要精确匹配的字段，聚合分析和排序操作。</li></ul><p>   示例模板：<br>   <div class="highlight-container" data-rel="Json"><figure class="iseeu highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;mappings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;email&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></div></p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5787.Elasticsearch%E7%9A%84Term%E3%80%81Match%E5%92%8CKeyword%E6%A3%80%E7%B4%A2%E7%B1%BB%E5%9E%8B%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5787.Elasticsearch%E7%9A%84Term%E3%80%81Match%E5%92%8CKeyword%E6%A3%80%E7%B4%A2%E7%B1%BB%E5%9E%8B%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-的-Term、Match-和-Keyword-检索类型有什么区别？"><a href="#Elasticsearch-的-Term、Match-和-Keyword-检索类型有什么区别？" class="headerlink"]]>
    </summary>
    <title>Elasticsearch 的 Term、Match 和 Keyword 检索类型有什么区别？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch查询" scheme="https://javai.tech/tags/Elasticsearch%E6%9F%A5%E8%AF%A2/"/>
    <content>
      <![CDATA[<h1 id="如何通过-Elasticsearch-实现复杂的查询过滤条件？"><a href="#如何通过-Elasticsearch-实现复杂的查询过滤条件？" class="headerlink" title="如何通过 Elasticsearch 实现复杂的查询过滤条件？"></a>如何通过 Elasticsearch 实现复杂的查询过滤条件？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>通过 Elasticsearch 实现复杂的查询过滤条件，通常需要使用其强大的搜索查询 DSL（Domain Specific Language）。具体来说，可以借助 Bool Query 来结合多个查询条件（must、should、must_not、filter）实现复杂的逻辑筛选。下面是一个实际例子，通过 Bool Query 实现复杂的查询：</p><div class="highlight-container" data-rel="Json"><figure class="iseeu highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;bool&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;must&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                <span class="punctuation">&#123;</span><span class="attr">&quot;match&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;status&quot;</span><span class="punctuation">:</span> <span class="string">&quot;active&quot;</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="punctuation">&#123;</span><span class="attr">&quot;range&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;age&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;gte&quot;</span><span class="punctuation">:</span> <span class="number">30</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;filter&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                <span class="punctuation">&#123;</span><span class="attr">&quot;term&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;gender&quot;</span><span class="punctuation">:</span> <span class="string">&quot;male&quot;</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;should&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                <span class="punctuation">&#123;</span><span class="attr">&quot;term&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;subscription&quot;</span><span class="punctuation">:</span> <span class="string">&quot;premium&quot;</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;must_not&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                <span class="punctuation">&#123;</span><span class="attr">&quot;term&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;country&quot;</span><span class="punctuation">:</span> <span class="string">&quot;USA&quot;</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">]</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></div><p>这里的查询条件实现了这样一种逻辑：必须满足 status 为 active 和 age 大于等于 30，同时性别是 male，优先推荐 subscription 为 premium，不包括 country 为 USA 的记录。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>查询子句解读</strong>：</p><ul><li><strong>must</strong>：必须匹配的查询条件，相当于逻辑“AND”。在上面的例子中，仅查找 status 为 active 而且 age 大于等于 30 的文档。</li><li><strong>filter</strong>：用于过滤文档，但它不影响评分计算。这个在性能上会更高效，适用于那些不需要评分计算的条件。在这里，我们过滤性别为 male 的文档。</li><li><strong>should</strong>：可选的查询条件，相当于逻辑“OR”。匹配 should 子句中的任意一个条件将提升文档的相关性评分。在这个例子中，是为了找到 subscription 为 premium 的文档。</li><li><strong>must_not</strong>：必须排除的查询条件，即不符合这些条件的文档。这个例子中，我们排除 country 为 USA 的文档。</li></ul><p>2）<strong>评分和优化</strong>：<br>在实际应用中，经常会遇到需要评分（scoring）和排序的情况。Elasticsearch 的 scoring 会根据查询条件的权重（boost）以及文档的相关性评分返回查询结果。对于时间敏感和性能敏感的查询，可以使用 <code>filter</code> 子句，因为它不会计算相关性评分，从而提升查询性能。</p><p>3）<strong>嵌套查询和子查询</strong>：<br>对于更为复杂的条件，可以使用 nested query 来处理嵌套对象，使用子查询可以更灵活地组合多个查询逻辑。例如，使用 <code>nested</code> 子句处理带有嵌套结构的 JSON 数据：</p><div class="highlight-container" data-rel="Json"><figure class="iseeu highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;nested&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;path&quot;</span><span class="punctuation">:</span> <span class="string">&quot;comments&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;bool&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                    <span class="attr">&quot;must&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">                        <span class="punctuation">&#123;</span><span class="attr">&quot;match&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;comments.user&quot;</span><span class="punctuation">:</span> <span class="string">&quot;kimchy&quot;</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">                        <span class="punctuation">&#123;</span><span class="attr">&quot;range&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;comments.date&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;gte&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2022-01-01&quot;</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span><span class="punctuation">&#125;</span></span><br><span class="line">                    <span class="punctuation">]</span></span><br><span class="line">                <span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></div><p>这个例子用于查询 comments 里 user 为 kimchy 且 date 大于等于 2022-01-01 的记录。</p><p>4）<strong>使用脚本进行高级查询</strong>：<br>Elasticsearch 允许使用脚本进行更高级的查询，尽管这可能会耗费更多资源。在 <code>_score</code> 子句里可以用脚本来控制评分逻辑。例如，用一个简单的 Painless 脚本来进行自定义评分：</p><div class="highlight-container" data-rel="Json"><figure class="iseeu highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;function_score&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;match&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="attr">&quot;title&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Elasticsearch&quot;</span><span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;script_score&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;script&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                    <span class="attr">&quot;source&quot;</span><span class="punctuation">:</span> <span class="string">&quot;doc[&#x27;views&#x27;].value * _score&quot;</span></span><br><span class="line">                <span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></div><p>这个例子中，评分由文档的 <code>views</code> 值乘以匹配查询的默认评分值。</p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5832.%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87Elasticsearch%E5%AE%9E%E7%8E%B0%E5%A4%8D%E6%9D%82%E7%9A%84%E6%9F%A5%E8%AF%A2%E8%BF%87%E6%BB%A4%E6%9D%A1%E4%BB%B6%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5832.%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87Elasticsearch%E5%AE%9E%E7%8E%B0%E5%A4%8D%E6%9D%82%E7%9A%84%E6%9F%A5%E8%AF%A2%E8%BF%87%E6%BB%A4%E6%9D%A1%E4%BB%B6%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="如何通过-Elasticsearch-实现复杂的查询过滤条件？"><a href="#如何通过-Elasticsearch-实现复杂的查询过滤条件？" class="headerlink" title="如何通过 Elasticsearch]]>
    </summary>
    <title>如何通过 Elasticsearch 实现复杂的查询过滤条件？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch客户端" scheme="https://javai.tech/tags/Elasticsearch%E5%AE%A2%E6%88%B7%E7%AB%AF/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-的-RestHighLevelClient-与-RestClient-有什么区别？如何选择使用？"><a href="#Elasticsearch-的-RestHighLevelClient-与-RestClient-有什么区别？如何选择使用？" class="headerlink" title="Elasticsearch 的 RestHighLevelClient 与 RestClient 有什么区别？如何选择使用？"></a>Elasticsearch 的 RestHighLevelClient 与 RestClient 有什么区别？如何选择使用？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 的 RestHighLevelClient 与 RestClient 的主要区别在于它们的抽象层次和使用的复杂度。</p><p>1）RestHighLevelClient 是基于 RestClient 之上的更高级的客户端，它封装了 Elasticsearch 的许多 API 调用，使得操作更加简单和直观。<br>2）RestClient 是更底层的客户端，操作更灵活，但同时需要开发者自己处理更多的细节，比如解析响应、错误处理等。</p><p>选择使用哪个客户端取决于以下因素：<br>1）如果你希望更快速地进行开发并且不想处理太多复杂的底层细节，推荐使用 RestHighLevelClient。<br>2）但如果你需要更细粒度的控制和更灵活的处理方式，则可以使用 RestClient。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>RestHighLevelClient 的优点和使用场景：</strong></p><ul><li><strong>简化开发</strong>：它封装了常用的 API，如搜索、索引、删除、更新等，使得开发者不需要自己编写复杂的 HTTP 请求。</li><li><strong>减少错误</strong>：由于封装了许多底层细节，使用 RestHighLevelClient 可以减少开发者手动解析响应时的错误。</li><li><strong>代码可读性和维护性更好</strong>：统一的接口定义和方法调用增强了代码的可读性和维护性。</li><li><strong>常见场景</strong>：大多数日常的 Elasticsearch 操作，比如全文搜索、索引管理等，都可以使用 RestHighLevelClient 来完成。</li></ul><p>2）<strong>RestClient 的优点和使用场景：</strong></p><ul><li><strong>灵活性高</strong>：适用于需要自定义请求和响应处理的场景，允许开发者完全控制 HTTP 请求。</li><li><strong>更适合复杂或不常见的操作</strong>：当需要执行 RestHighLevelClient 不支持的操作时，可以直接使用 RestClient 发送自定义的 HTTP 请求。</li><li><strong>性能优化</strong>：在性能敏感的场景中，可以通过自定义的方式来进行更高效的请求和响应处理。</li></ul><p>3）<strong>选择的策略：</strong></p><ul><li><strong>初期开发</strong>：如果项目刚开始，建议优先使用 RestHighLevelClient，因为其简单直观、省时省力。</li><li><strong>性能优化和定制需求</strong>：在后续的优化和特殊需求时，可以引入 RestClient 进行补充，或者直接过渡到 RestClient 以获取更加灵活的控制。</li></ul><p>4）<strong>版本兼容性</strong>：</p><ul><li><strong>Elasticsearch 版本</strong>：不同版本的 Elasticsearch 可能会对 RestHighLevelClient 和 RestClient 的支持存在差异，建议查看对应版本的官方文档以获取最新的信息。</li><li><strong>API 稳定性</strong>：RestHighLevelClient 的 API 更加稳定和受官方推荐，被广泛使用和测试，因此在面对未来版本升级时，可能会相对省心。</li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5865.Elasticsearch%E7%9A%84RestHighLevelClient%E4%B8%8ERestClient%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9%E4%BD%BF%E7%94%A8%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5865.Elasticsearch%E7%9A%84RestHighLevelClient%E4%B8%8ERestClient%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9%E4%BD%BF%E7%94%A8%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-的-RestHighLevelClient-与-RestClient-有什么区别？如何选择使用？"><a]]>
    </summary>
    <title>Elasticsearch 的 RestHighLevelClient 与 RestClient 有什么区别？如何选择使用？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch客户端" scheme="https://javai.tech/tags/Elasticsearch%E5%AE%A2%E6%88%B7%E7%AB%AF/"/>
    <content>
      <![CDATA[<h1 id="如何通过-Spring-Data-Elasticsearch-简化与-Elasticsearch-的集成？"><a href="#如何通过-Spring-Data-Elasticsearch-简化与-Elasticsearch-的集成？" class="headerlink" title="如何通过 Spring Data Elasticsearch 简化与 Elasticsearch 的集成？"></a>如何通过 Spring Data Elasticsearch 简化与 Elasticsearch 的集成？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>我们可以通过 Spring Data Elasticsearch 简化与 Elasticsearch 的集成。这是因为 Spring Data Elasticsearch 提供了一套高级别的 API，能够帮助我们更加方便地操作 Elasticsearch。具体步骤如下：</p><p>1）我们首先需要在项目中引入 Spring Data Elasticsearch 的依赖。<br>2）然后，需要在 Spring Boot 应用程序中配置 Elasticsearch 相关的信息，比如集群的地址和端口。<br>3）接下来，我们可以定义一个实体类来对应 Elasticsearch 的索引。<br>4）通过扩展 ElasticSearchRepository（或者 ReactiveElasticSearchRepository），我们可以创建自己的仓库接口，这个接口将提供出一些基本的 CRUD 操作方法，还可以自定义查询方法。<br>5）最后，我们可以通过自动注入这些仓库接口，来实现我们的业务逻辑。</p><p>这样通过以上的步骤，我们就能够非常轻松地实现与 Elasticsearch 的集成，大幅度减少我们直接处理 Elasticsearch 具体 API 的复杂性。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>Spring Data Elasticsearch不仅提供了简洁的 CRUD 操作接口，还支持自定义查询和复杂查询。我们可以通过命名查询方法或使用 @Query 注解来自定义查询逻辑。比如，可以像这样编写一个自定义查询接口：</p><div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">ProductRepository</span> <span class="keyword">extends</span> <span class="title class_">ElasticsearchRepository</span>&lt;Product, String&gt; &#123;</span><br><span class="line">    List&lt;Product&gt; <span class="title function_">findByName</span><span class="params">(String name)</span>;  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><p>除了 CRUD 和简单查询外，Spring Data Elasticsearch 还支持以下功能：</p><p>1）<strong>全文检索</strong> - 可以使用 Annotation 来标识哪个字段是索引字段，那么在查询时可以像全文检索那样进行搜索。<br>2）<strong>分页和排序</strong> - 使用 Pageable 和 Sort 进行分页和排序。<br>3）<strong>自定义实体映射</strong> - 如果默认映射不符合需求，你可以自定义实体与 Elasticsearch 文档之间的映射。<br>4）<strong>聚合操作</strong> - 支持 Elasticsearch 的聚合查询。</p><p>扩展阅读材料：</p><ul><li><a class="link"   href="https://spring.io/projects/spring-data-elasticsearch" >Spring Data Elasticsearch 官方文档 <i class="fa-regular fa-arrow-up-right-from-square fa-sm"></i></a></li><li><a class="link"   href="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" >Elasticsearch 的官方文档 <i class="fa-regular fa-arrow-up-right-from-square fa-sm"></i></a></li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5867.%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87SpringDataElasticsearch%E7%AE%80%E5%8C%96%E4%B8%8EElasticsearch%E7%9A%84%E9%9B%86%E6%88%90%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/ElasticSearch%E9%9D%A2%E8%AF%95%E9%A2%98/5867.%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87SpringDataElasticsearch%E7%AE%80%E5%8C%96%E4%B8%8EElasticsearch%E7%9A%84%E9%9B%86%E6%88%90%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="如何通过-Spring-Data-Elasticsearch-简化与-Elasticsearch-的集成？"><a href="#如何通过-Spring-Data-Elasticsearch-简化与-Elasticsearch-的集成？"]]>
    </summary>
    <title>如何通过 Spring Data Elasticsearch 简化与 Elasticsearch 的集成？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch 原理面试题" scheme="https://javai.tech/categories/Elasticsearch-%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch原理" scheme="https://javai.tech/tags/Elasticsearch%E5%8E%9F%E7%90%86/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-中分词功能的实现原理是什么？"><a href="#Elasticsearch-中分词功能的实现原理是什么？" class="headerlink" title="Elasticsearch 中分词功能的实现原理是什么？"></a>Elasticsearch 中分词功能的实现原理是什么？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 中分词功能的实现，是通过它的分析器（Analyzer）组件完成的。分析器包含三个部分：字符过滤器（Character Filters）、分词器（Tokenizer）和标记过滤器（Token Filters）。分词的主要过程是将文本字符串处理成一系列有意义的词汇单元（Tokens），便于索引和搜索。</p><p>1）<strong>字符过滤器</strong>：首先，字符过滤器会预处理输入文本，请注意这一步往往是可选的。常见的操作包括去除或替换特殊字符、HTML 解码等。</p><p>2）<strong>分词器</strong>：其次，核心分词器（Tokenizer）会将输入文本根据一定的规则拆分成一个个的词汇单元（Tokens）。比如标准的分词器会根据空格和标点符号来拆分文本。</p><p>3）<strong>标记过滤器</strong>：最后，标记过滤器（Token Filters）会对这些词汇单元进行处理，如转小写、去除停用词（比如”the”、”and”）等，让分词结果更加符合搜索意图。</p><p>总之，分词功能的实现原理由上述三个阶段组成，它们协作地将文本转换成适合存储和搜索的词汇单元。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>字符过滤器的作用</strong>：字符过滤器在文本进入分词器之前进行预处理。比如 HTML Strip 字符过滤器会去除 HTML 标签，而 Mapping 字符过滤器可以用来将特定字符映射为其他字符。</p><p>2）<strong>分词器的多样性</strong>：Elasticsearch 提供了多种内置的分词器，例如：</p><ul><li><strong>Standard Tokenizer</strong>：默认的标准分词器，按词语和标点符号分割。</li><li><strong>Whitespace Tokenizer</strong>：仅仅根据空格进行分割，不考虑标点符号。</li><li><strong>NGram Tokenizer</strong>：生成部分词汇，适用于模糊搜索。</li><li><strong>Edge NGram Tokenizer</strong>：生成前缀词汇。</li></ul><p>3）<strong>标记过滤器的丰富性</strong>：标记过滤器用于词汇单元的进一步处理。例如：</p><ul><li><strong>Lowercase Token Filter</strong>：将所有词汇单元转换为小写。</li><li><strong>Stop Token Filter</strong>：移除常见但无意义的停用词，如”is”、”the”等。</li><li><strong>Synonym Token Filter</strong>：扩展词汇单元以包含同义词。</li></ul><p>4）<strong>自定义分析器</strong>：用户可以根据需求自定义自己的分析器，包括选择和配置字符过滤器、分词器和标记过滤器。这让 Elasticsearch 的分词功能非常灵活。</p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5795.Elasticsearch%E4%B8%AD%E5%88%86%E8%AF%8D%E5%8A%9F%E8%83%BD%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5795.Elasticsearch%E4%B8%AD%E5%88%86%E8%AF%8D%E5%8A%9F%E8%83%BD%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-中分词功能的实现原理是什么？"><a href="#Elasticsearch-中分词功能的实现原理是什么？" class="headerlink" title="Elasticsearch]]>
    </summary>
    <title>Elasticsearch 中分词功能的实现原理是什么？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch 原理面试题" scheme="https://javai.tech/categories/Elasticsearch-%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch原理" scheme="https://javai.tech/tags/Elasticsearch%E5%8E%9F%E7%90%86/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-的倒排索引与-MySQL-的正排索引有什么区别？"><a href="#Elasticsearch-的倒排索引与-MySQL-的正排索引有什么区别？" class="headerlink" title="Elasticsearch 的倒排索引与 MySQL 的正排索引有什么区别？"></a>Elasticsearch 的倒排索引与 MySQL 的正排索引有什么区别？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 的倒排索引和 MySQL 的正排索引在数据存储和查询优化方面的实现策略和应用场景上有明显区别：</p><p>1）<strong>倒排索引（Elasticsearch）</strong>：倒排索引是一种为了快速全文检索而设计的数据结构。它将文档中的每一个唯一的词汇（Term）映射到包含这个词汇的文档列表，这样在搜索时，可以快速定位包含特定词汇的文档。</p><p>2）<strong>正排索引（MySQL）</strong>：正排索引主要用于传统关系型数据库，它将每行的数据按照主键或某个字段的顺序排列并建立索引。当进行查询时，它通过索引快速定位到满足查询条件的行，然后读取数据。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>为了更全面地理解两者的区别和使用场景，以下是两者的详细对比：</p><p>1）<strong>数据结构</strong>：</p><ul><li><strong>倒排索引</strong>：存储的是Term到文档ID的映射，即（Term -&gt; Document IDs）。这使得在进行全文搜索时，能快速找到包含某个词汇的所有文档。</li><li><strong>正排索引</strong>：存储的是记录中的字段值，按某个字段排序并索引（如B+树）。通过这个索引，可以快速定位到特定的记录。</li></ul><p>2）<strong>应用场景</strong>：</p><ul><li><strong>倒排索引</strong>：适用于需要快速进行全文搜索的场景，如文本搜索、日志分析等。Elasticsearch正是利用倒排索引实现了高效的全文检索。</li><li><strong>正排索引</strong>：适用于传统数据库的按主键或指定字段进行查找的场景，如事务型应用、关系型数据查询等。MySQL常用于事务处理和结构化数据管理。</li></ul><p>3）<strong>查询速度</strong>：</p><ul><li><strong>倒排索引</strong>：在处理搜索和关联查询时非常高效，尤其是大规模文本文档的查询。例如，在搜索“apple”这个词时，可以立即返回包含“apple”的所有文档ID。</li><li><strong>正排索引</strong>：在精确查找和范围查询（如查找特定ID或时间范围内的记录）时表现优异。例如，在查询user_id为某个特定值的数据时，可以迅速定位。</li></ul><p>4）<strong>更新操作</strong>：</p><ul><li><strong>倒排索引</strong>：更新和删除操作会更复杂，因为涉及到倒排索引的重建或调整，这可能会影响查询的实时性。</li><li><strong>正排索引</strong>：更新操作较为简单，适合频繁的增删改操作。例如在一个用户表中频繁更新用户信息，正排索引能很快地响应这些变化。</li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5801.Elasticsearch%E7%9A%84%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%E4%B8%8EMySQL%E7%9A%84%E6%AD%A3%E6%8E%92%E7%B4%A2%E5%BC%95%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5801.Elasticsearch%E7%9A%84%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%E4%B8%8EMySQL%E7%9A%84%E6%AD%A3%E6%8E%92%E7%B4%A2%E5%BC%95%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-的倒排索引与-MySQL-的正排索引有什么区别？"><a href="#Elasticsearch-的倒排索引与-MySQL-的正排索引有什么区别？" class="headerlink" title="Elasticsearch]]>
    </summary>
    <title>Elasticsearch 的倒排索引与 MySQL 的正排索引有什么区别？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch 原理面试题" scheme="https://javai.tech/categories/Elasticsearch-%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch原理" scheme="https://javai.tech/tags/Elasticsearch%E5%8E%9F%E7%90%86/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-如何根据词汇找到对应的倒排索引？经历哪些步骤？"><a href="#Elasticsearch-如何根据词汇找到对应的倒排索引？经历哪些步骤？" class="headerlink" title="Elasticsearch 如何根据词汇找到对应的倒排索引？经历哪些步骤？"></a>Elasticsearch 如何根据词汇找到对应的倒排索引？经历哪些步骤？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>在Elasticsearch中，搜索是基于倒排索引进行的。当你根据给定的词汇（term）查找对应的倒排索引时，主要会经历以下步骤：</p><ol><li><strong>分词处理</strong>：首先，将查询的词汇进行分词处理。Elasticsearch会使用指定的分词器（Analyzer）将输入的查询拆分成多个词项（terms）。</li><li><strong>寻找词项</strong>：接着，Elasticsearch会在索引中查找与这些词项相对应的倒排索引。</li><li><strong>访问倒排索引</strong>：每个词项对应的倒排索引被找到后，Elasticsearch会访问这些倒排索引以查找所有包含该词项的文档ID。</li><li><strong>合并结果</strong>：最后，将查找到的文档ID根据某种逻辑（例如，布尔查询）进行合并，并返回给用户。</li></ol><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>这些步骤看似简单，但每个步骤都有很多细节和优化。以下是一些关键的附加知识：</p><ol><li><p><strong>分词器和标准化</strong>：</p><ul><li>不同的语言和应用场景会有不同的分词器。例如，标准的分词器（standard analyzer）适用于大部分英文文本，而中文可能需要使用ik分词器。</li><li>分词器不仅仅是简单地拆词，还会进行词项的标准化（如：小写转换、去除停用词等）。</li></ul></li><li><p><strong>倒排索引的结构</strong>：</p><ul><li>倒排索引的核心结构是一个词项（term）到文档ID列表（posting list）的映射。每个词项存储在一个B树或B+树等数据结构中，方便高速查找。</li><li>每个词项不仅记录文档ID，还可能记录词频（TF）、文档频率（DF）等信息，用于后续的相关性计算。</li></ul></li><li><p><strong>多字段搜索</strong>：</p><ul><li>在实际应用中，搜索不仅限于单个字段，通常会涉及多个字段。Elasticsearch通过Multi-Field搜索（例如，Multi-Match Query）来处理这种情况，不同字段可以有不同的权重（boost）。</li></ul></li><li><p><strong>缓存与优化</strong>：</p><ul><li>为了提高搜索性能，Elasticsearch会对一些频繁搜索的词项和查询结果进行缓存。此外，Elasticsearch还会合并多个小的倒排索引段（segment）以减少查询时的I&#x2F;O开销。</li></ul></li><li><p><strong>相关性评分与排序</strong>：</p><ul><li>最后，根据查询结果，Elasticsearch会计算每个文档的相关性评分，这是通过可扩展的评分机制（例如TF-IDF、BM25等）来实现。根据这些评分，结果按照相关性进行排序，返回给用户。</li></ul></li></ol>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5802.Elasticsearch%E5%A6%82%E4%BD%95%E6%A0%B9%E6%8D%AE%E8%AF%8D%E6%B1%87%E6%89%BE%E5%88%B0%E5%AF%B9%E5%BA%94%E7%9A%84%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%EF%BC%9F%E7%BB%8F%E5%8E%86%E5%93%AA%E4%BA%9B%E6%AD%A5%E9%AA%A4%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5802.Elasticsearch%E5%A6%82%E4%BD%95%E6%A0%B9%E6%8D%AE%E8%AF%8D%E6%B1%87%E6%89%BE%E5%88%B0%E5%AF%B9%E5%BA%94%E7%9A%84%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%EF%BC%9F%E7%BB%8F%E5%8E%86%E5%93%AA%E4%BA%9B%E6%AD%A5%E9%AA%A4%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-如何根据词汇找到对应的倒排索引？经历哪些步骤？"><a href="#Elasticsearch-如何根据词汇找到对应的倒排索引？经历哪些步骤？" class="headerlink" title="Elasticsearch]]>
    </summary>
    <title>Elasticsearch 如何根据词汇找到对应的倒排索引？经历哪些步骤？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch 原理面试题" scheme="https://javai.tech/categories/Elasticsearch-%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch原理" scheme="https://javai.tech/tags/Elasticsearch%E5%8E%9F%E7%90%86/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-中倒排索引的结构具体是怎样的？"><a href="#Elasticsearch-中倒排索引的结构具体是怎样的？" class="headerlink" title="Elasticsearch 中倒排索引的结构具体是怎样的？"></a>Elasticsearch 中倒排索引的结构具体是怎样的？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>在Elasticsearch中，倒排索引（Inverted Index）是其核心的数据结构，用于高效地进行全文搜索。倒排索引的基本结构如下：</p><p>1）<strong>术语字典（Term Dictionary）</strong>：存储所有文本文档中出现的唯一术语（也叫词项），并按字典序进行排序。<br>2）<strong>术语列表（Term List）</strong>：每个唯一术语都会关联一个包含它的文档列表，项目中仍然是以文档ID为索引分布的。<br>3）<strong>倒排文件索引（Inverted File Index）</strong>：对于每个术语，记录了包含该术语的所有文档的列表，通常可以包括位置信息、频率信息等，用于在文档中查找定位。</p><p>举个例子，假设有以下三个文档：</p><ul><li>Doc1: “Elasticsearch is a search engine”</li><li>Doc2: “Elasticsearch uses an inverted index”</li><li>Doc3: “An inverted index is used in search engines”</li></ul><p>倒排索引会从这些文档提取术语并建立如下结构：<br>术语：{ “An”, “Elasticsearch”, “a”, “engine”, “engines”, “in”, “index”, “inverted”, “is”, “search”, “used”, “uses” }<br>倒排文件索引：</p><ul><li>“An” -&gt; Doc3</li><li>“Elasticsearch” -&gt; Doc1, Doc2</li><li>“a” -&gt; Doc1</li><li>“engine” -&gt; Doc1</li><li>“engines” -&gt; Doc3</li><li>…</li></ul><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>术语位置和频率</strong>：倒排索引不仅仅只记录术语对应的文档ID，还记录了术语在每个文档中出现的位置和频率。这些信息在排序、聚合和高效的快速查询中都非常重要。例如，Elasticsearch能够快速高效地计算出某个术语在特定段落或者文档中的出现次数及其相对位置。</p><p>2）<strong>分片和副本</strong>：Elasticsearch依赖倒排索引来快速检索分片中的数据。集群中的每个索引会分成多个主分片（Primary Shards）和副本分片（Replica Shards），分片中的每一个都会维护自己的倒排索引。</p><p>3）<strong>压缩技术</strong>：由于倒排索引可能会消耗大量存储空间，Elasticsearch应用了多种压缩技术来减少索引数据的存储需求，如字典编码、前缀压缩和格里布编码。这些技术可以极大地压缩索引文件的体积，提高检索速度和效率。</p><p>4）<strong>Lucene库</strong>：在Elasticsearch的底层实现中，实际上是使用了Apache Lucene库。Lucene提供了创建和管理倒排索引的所有基础设施，因此它是Elasticsearch高效搜索能力的根基。</p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5803.Elasticsearch%E4%B8%AD%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%E7%9A%84%E7%BB%93%E6%9E%84%E5%85%B7%E4%BD%93%E6%98%AF%E6%80%8E%E6%A0%B7%E7%9A%84%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5803.Elasticsearch%E4%B8%AD%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%E7%9A%84%E7%BB%93%E6%9E%84%E5%85%B7%E4%BD%93%E6%98%AF%E6%80%8E%E6%A0%B7%E7%9A%84%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-中倒排索引的结构具体是怎样的？"><a href="#Elasticsearch-中倒排索引的结构具体是怎样的？" class="headerlink" title="Elasticsearch]]>
    </summary>
    <title>Elasticsearch 中倒排索引的结构具体是怎样的？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch 原理面试题" scheme="https://javai.tech/categories/Elasticsearch-%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch原理" scheme="https://javai.tech/tags/Elasticsearch%E5%8E%9F%E7%90%86/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-底层如何执行文档的更新和删除操作？详细流程是什么？"><a href="#Elasticsearch-底层如何执行文档的更新和删除操作？详细流程是什么？" class="headerlink" title="Elasticsearch 底层如何执行文档的更新和删除操作？详细流程是什么？"></a>Elasticsearch 底层如何执行文档的更新和删除操作？详细流程是什么？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 底层是通过一种叫做 <strong>“近实时搜索（NRT - Near Real-Time Search）”</strong> 的方式来处理文档的更新和删除操作的。具体来说：<br>1）<strong>更新操作</strong>实际上是先删除旧文档，然后插入新文档。<br>2）<strong>删除操作</strong>并不会立即将文档从磁盘中移除，而是标记为“已删除”。</p><h3 id="更新操作详细流程："><a href="#更新操作详细流程：" class="headerlink" title="更新操作详细流程："></a>更新操作详细流程：</h3><p>1）客户端发起更新请求。<br>2）Elasticsearch 接收到更新请求，将请求转发到负责该文档的主分片。<br>3）主分片进行版本控制，确保数据的一致性。<br>4）Elasticsearch 先将旧文档标记为删除，然后创建一个新版本的文档。<br>5）主分片将更改记录到事务日志（Translog）中，确保数据在故障恢复时不丢失。<br>6）最后，将更新同步到副本分片，确保高可用性。</p><h3 id="删除操作详细流程："><a href="#删除操作详细流程：" class="headerlink" title="删除操作详细流程："></a>删除操作详细流程：</h3><p>1）客户端发起删除请求。<br>2）Elasticsearch 将该请求转给相应的主分片。<br>3）主分片检查文档的版本信息，确保没有并发冲突。<br>4）不是立即删除文档，而是将其标记为“已删除”状态。<br>5）将删除操作记录到事务日志（Translog）中。<br>6）在适当的时间，经过段合并（Segment Merge）操作，彻底从磁盘上移除标记为删除的文档。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>文档版本控制</strong></p><ul><li>Elasticsearch 使用的是乐观并发控制（Optimistic Concurrency Control）来实现文档的版本控制。在插入或更新文档时，版本号都会自动递增。</li></ul><p>2）<strong>事务日志（Translog）</strong></p><ul><li>Translog 是 Elasticsearch 保证数据可靠性的关键。当数据写入时，除了写入内存还会写入 Translog，这样即使发生故障，系统也可以根据 Translog 进行数据恢复。</li></ul><p>3）<strong>段合并（Segment Merge）</strong></p><ul><li>当文档被标记为删除或者数据更新后，原来的文档不会立刻从磁盘中移除。Elasticsearch 会在适当的时间进行“段合并”，将标记为删除的文档实际从磁盘移除并合并小段为大段，以提高查询效率。</li></ul><p>4）<strong>近实时搜索（NRT）</strong></p><ul><li>Elasticsearch 的更新和删除操作并不是立刻可见的，而是近实时的。通常会有一个很短的延迟（默认值是 1 秒），数据才会被刷新到搜索索引中。</li></ul><p>5）<strong>副本分片同步</strong></p><ul><li>主分片处理完操作后，会将更改同步到所有副本分片。这是为了保证高可用性，当主分片失效时，副本分片可以立刻顶上，不会影响数据的可用性。</li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5869.Elasticsearch%E5%BA%95%E5%B1%82%E5%A6%82%E4%BD%95%E6%89%A7%E8%A1%8C%E6%96%87%E6%A1%A3%E7%9A%84%E6%9B%B4%E6%96%B0%E5%92%8C%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C%EF%BC%9F%E8%AF%A6%E7%BB%86%E6%B5%81%E7%A8%8B%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5869.Elasticsearch%E5%BA%95%E5%B1%82%E5%A6%82%E4%BD%95%E6%89%A7%E8%A1%8C%E6%96%87%E6%A1%A3%E7%9A%84%E6%9B%B4%E6%96%B0%E5%92%8C%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C%EF%BC%9F%E8%AF%A6%E7%BB%86%E6%B5%81%E7%A8%8B%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-底层如何执行文档的更新和删除操作？详细流程是什么？"><a href="#Elasticsearch-底层如何执行文档的更新和删除操作？详细流程是什么？" class="headerlink" title="Elasticsearch]]>
    </summary>
    <title>Elasticsearch 底层如何执行文档的更新和删除操作？详细流程是什么？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch 原理面试题" scheme="https://javai.tech/categories/Elasticsearch-%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch原理" scheme="https://javai.tech/tags/Elasticsearch%E5%8E%9F%E7%90%86/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-底层是如何实现数据存储的？比如数据的存储流程和管理机制"><a href="#Elasticsearch-底层是如何实现数据存储的？比如数据的存储流程和管理机制" class="headerlink" title="Elasticsearch 底层是如何实现数据存储的？比如数据的存储流程和管理机制"></a>Elasticsearch 底层是如何实现数据存储的？比如数据的存储流程和管理机制</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 底层的数据存储主要依赖于 Apache Lucene，它通过将数据存储在倒排索引的结构中来实现快速的全文搜索。简言之，Elasticsearch 会将插入的数据文档拆分成一个个的“倒排索引”（Inverted Index），然后存储在分片（Shard）中。每个索引由多个分片组成，每个分片又进一步拆分为多个段（Segment）。这些段是 Lucene 管理数据存储和检索的基本单元。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1） <strong>倒排索引</strong>：倒排索引是一种高效的文本检索数据结构。它主要包括两个部分：词典（dictionary）和倒排列表（postings list）。词典包含了文档中出现的所有单词，而倒排列表为每个单词储存对应的文档和位置信息。倒排索引使得 Elasticsearch 能够迅速的找到包含特定关键词的文档。</p><p>2） <strong>分片和副本</strong>：为了实现数据的分布式存储和高可用性，Elasticsearch 将索引拆分为分片（primary shard），并为每个分片复制多个副本（replica shard）。这样做不仅可以提升读取性能，还能在某些分片失效时保证数据不丢失。默认情况下，一个索引有5个主分片和1个分片副本。</p><p>3） <strong>段（Segment）管理</strong>：Lucene 将每个分片进一步拆分为多个段。段是不可变的文件，存储最终的数据。每个索引操作（比如新增或更新文档）都会生成新的段，这些段会定期进行合并操作（Merge），以减少文件数量并优化查询性能。</p><p>4） <strong>文档写入流程</strong>：</p><ul><li>当我们向 Elasticsearch 插入一条数据，数据首先被写入到名为 translog 的事务日志文件中，该过程确保数据不会丢失，即使节点突然宕机。</li><li>同时，数据会被解析，构建倒排索引，并写入到段文件中。</li><li>默认情况下，Elasticsearch 每隔一秒钟会刷新 translog，将缓存中的变更写入到新的段中，并构建新的倒排索引结构。</li></ul><p>5） <strong>数据管理</strong>：</p><ul><li><strong>刷新（Refresh）</strong>：默认情况下，Elasticsearch 每秒进行一次刷新，来执行数据持久化和倒排索引创建。</li><li><strong>合并（Merge）</strong>：为了避免段文件数量增长太多，Lucene 会定期进行段合并。合并会将小段合并成大段，减少文件数量，提升查询效率。合并策略是 Elasticsearch 性能调优的重要的一环。</li></ul><p>6） <strong>数据查询</strong>：倒排索引的结构使得查询效率非常高。当用户发起查询请求时，Elasticsearch 会用查询关键词在倒排索引中迅速找到对应的文档列表，从而实现快速的全文检索功能。</p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5875.Elasticsearch%E5%BA%95%E5%B1%82%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E7%9A%84%EF%BC%9F%E6%AF%94%E5%A6%82%E6%95%B0%E6%8D%AE%E7%9A%84%E5%AD%98%E5%82%A8%E6%B5%81%E7%A8%8B%E5%92%8C%E7%AE%A1%E7%90%86%E6%9C%BA%E5%88%B6/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5875.Elasticsearch%E5%BA%95%E5%B1%82%E6%98%AF%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E7%9A%84%EF%BC%9F%E6%AF%94%E5%A6%82%E6%95%B0%E6%8D%AE%E7%9A%84%E5%AD%98%E5%82%A8%E6%B5%81%E7%A8%8B%E5%92%8C%E7%AE%A1%E7%90%86%E6%9C%BA%E5%88%B6/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-底层是如何实现数据存储的？比如数据的存储流程和管理机制"><a href="#Elasticsearch-底层是如何实现数据存储的？比如数据的存储流程和管理机制" class="headerlink"]]>
    </summary>
    <title>Elasticsearch 底层是如何实现数据存储的？比如数据的存储流程和管理机制</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch 原理面试题" scheme="https://javai.tech/categories/Elasticsearch-%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch原理" scheme="https://javai.tech/tags/Elasticsearch%E5%8E%9F%E7%90%86/"/>
    <category term="Lucene" scheme="https://javai.tech/tags/Lucene/"/>
    <content>
      <![CDATA[<h1 id="如何在-Lucene-中实现倒排索引？"><a href="#如何在-Lucene-中实现倒排索引？" class="headerlink" title="如何在 Lucene 中实现倒排索引？"></a>如何在 Lucene 中实现倒排索引？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>在 Lucene 中实现倒排索引是它的核心功能之一。倒排索引是一种高效存储和检索文本数据的结构，能够快速找到包含某个特定词的文档。为此，我们可以使用 Lucene 的 API 来创建、添加文档到索引和进行查询。以下是实现倒排索引的基本步骤：</p><p>1）创建一个 <code>IndexWriter</code> 实例 —— 这个类负责将文档写入索引。<br>2）定义一个文档（<code>Document</code>）并添加域（<code>Field</code>）—— 文档是索引的基本单位，每个文档由若干个域组成。<br>3）向索引中添加文档。<br>4）关闭 <code>IndexWriter</code>。<br>5）创建 <code>IndexReader</code> 和 <code>IndexSearcher</code> 实例以进行查询。</p><p>这里给出一个简单的示例来说明这些步骤：</p><div class="highlight-container" data-rel="Java"><figure class="iseeu highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.apache.lucene.analysis.standard.StandardAnalyzer;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.document.Document;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.document.Field;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.document.TextField;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.index.DirectoryReader;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.index.IndexWriter;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.index.IndexWriterConfig;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.queryparser.classic.QueryParser;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.search.IndexSearcher;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.search.Query;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.search.TopDocs;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.store.Directory;</span><br><span class="line"><span class="keyword">import</span> org.apache.lucene.store.RAMDirectory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LuceneDemo</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="comment">// 创建内存中索引的目录</span></span><br><span class="line">        <span class="type">Directory</span> <span class="variable">directory</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RAMDirectory</span>();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建标准分析器</span></span><br><span class="line">        <span class="type">StandardAnalyzer</span> <span class="variable">analyzer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StandardAnalyzer</span>();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建IndexWriter配置</span></span><br><span class="line">        <span class="type">IndexWriterConfig</span> <span class="variable">config</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">IndexWriterConfig</span>(analyzer);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建IndexWriter</span></span><br><span class="line">        <span class="type">IndexWriter</span> <span class="variable">writer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">IndexWriter</span>(directory, config);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建示例文档并添加到索引</span></span><br><span class="line">        <span class="type">Document</span> <span class="variable">doc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Document</span>();</span><br><span class="line">        doc.add(<span class="keyword">new</span> <span class="title class_">TextField</span>(<span class="string">&quot;content&quot;</span>, <span class="string">&quot;Lucene is a powerful search library&quot;</span>, Field.Store.YES));</span><br><span class="line">        writer.addDocument(doc);</span><br><span class="line">        writer.close();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建IndexReader</span></span><br><span class="line">        <span class="type">DirectoryReader</span> <span class="variable">reader</span> <span class="operator">=</span> DirectoryReader.open(directory);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建IndexSearcher</span></span><br><span class="line">        <span class="type">IndexSearcher</span> <span class="variable">searcher</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">IndexSearcher</span>(reader);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建查询解析器</span></span><br><span class="line">        <span class="type">QueryParser</span> <span class="variable">parser</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">QueryParser</span>(<span class="string">&quot;content&quot;</span>, analyzer);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 解析查询</span></span><br><span class="line">        <span class="type">Query</span> <span class="variable">query</span> <span class="operator">=</span> parser.parse(<span class="string">&quot;Lucene&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 搜索文档</span></span><br><span class="line">        <span class="type">TopDocs</span> <span class="variable">results</span> <span class="operator">=</span> searcher.search(query, <span class="number">10</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;Total Hits: &quot;</span> + results.totalHits.value);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 关闭IndexReader</span></span><br><span class="line">        reader.close();</span><br><span class="line">        directory.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><p>这个代码创建了一个简单的内存索引，并搜索包含“Lucene”这个词的文档。对于生产环境，通常将索引存储在磁盘上，而不是内存中。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>倒排索引的原理</strong>：倒排索引的核心是它通过持有倒排列表（即每个术语对应的文档列表）能够迅速定位包含该术语的所有文档，相比于扫描全部文档来说这是非常高效的。</p><p>2）<strong>Lucene 的分析器</strong>：Lucene 的分析器（Analyzer）用于对文本进行分词，建立词项（Term），分析器有多种类型，可以根据需求选择或自定义合适的分析器。</p><p>3）<strong>Lucene 索引结构</strong>：Lucene 的索引结构包括多个层次，索引（Index）包含多个段（Segment），每个段是一个独立的倒排索引文件，搜索时会合并这些段的结果，大规模索引还涉及到索引合并（Merge）操作。</p><p>4）<strong>TokenStream 和分词</strong>：TokenStream 是分析器内部的一部分，它负责将输入的文本流转换为标记流，实际的分词操作在这个过程中完成。</p><p>5）<strong>Query 类的不同实现</strong>：Lucene 提供了多种查询方式，如 TermQuery、PhraseQuery、BooleanQuery 等，通过这些查询方式可以构建非常复杂的搜索条件。</p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5878.%E5%A6%82%E4%BD%95%E5%9C%A8Lucene%E4%B8%AD%E5%AE%9E%E7%8E%B0%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5878.%E5%A6%82%E4%BD%95%E5%9C%A8Lucene%E4%B8%AD%E5%AE%9E%E7%8E%B0%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="如何在-Lucene-中实现倒排索引？"><a href="#如何在-Lucene-中实现倒排索引？" class="headerlink" title="如何在 Lucene 中实现倒排索引？"></a>如何在 Lucene 中实现倒排索引？</h1><h2]]>
    </summary>
    <title>如何在 Lucene 中实现倒排索引？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch 原理面试题" scheme="https://javai.tech/categories/Elasticsearch-%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch原理" scheme="https://javai.tech/tags/Elasticsearch%E5%8E%9F%E7%90%86/"/>
    <content>
      <![CDATA[<h1 id="什么是-Elasticsearch-的-Posting-List-倒排列表？"><a href="#什么是-Elasticsearch-的-Posting-List-倒排列表？" class="headerlink" title="什么是 Elasticsearch 的 Posting List 倒排列表？"></a>什么是 Elasticsearch 的 Posting List 倒排列表？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 的 Posting List，也叫倒排列表，是一种数据结构，用于快速查找包含某个单词或词条（term）的文档集合。在搜索引擎中，它是用来解决查询效率问题的核心组件。当我们进行搜索时，Elasticsearch 会通过倒排列表迅速确定所有包含查询词条的文档，从而大大提高搜索速度。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>倒排列表的构成</strong>：</p><p>  倒排列表包含两个主要部分：</p><ul><li><strong>Term</strong>：每个词条，即不同的单词或词语。</li><li><strong>Posting List</strong>：与某个词条相对应的文档ID列表，表示哪些文档中包含了这个词条。</li></ul><p>  举例来说，如果有三个文档：<br>    - Doc1: “Elasticsearch is powerful”<br>    - Doc2: “Elastic is flexible”<br>    - Doc3: “Elasticsearch is powerful and flexible”</p><p>  倒排列表会被构造成如下：<br>    - Term: “Elasticsearch” -&gt; Posting List: [Doc1, Doc3]<br>    - Term: “is” -&gt; Posting List: [Doc1, Doc2, Doc3]<br>    - Term: “powerful” -&gt; Posting List: [Doc1, Doc3]<br>    - Term: “and” -&gt; Posting List: [Doc3]<br>    - Term: “flexible” -&gt; Posting List: [Doc2, Doc3]</p><p>2）<strong>倒排列表的建立</strong>：</p><p>  当文档被索引的时候，Elasticsearch 会分析文档内容，将其分解为多个词条，并建立倒排列表。这个过程包括以下步骤：</p><ul><li>分词：将文档分成独立的词条。</li><li>标准化：将词条转换为标准形式，例如去掉标点符号，转为小写字母等。</li><li>建立倒排列表：将词条对应的文档ID加入到倒排列表中。</li></ul><p>3）<strong>查询优化</strong>：</p><p>  Elasticsearch 的倒排列表不仅能快速找到包含某个词条的文档，还可以进行进一步的优化：</p><ul><li><strong>跳表（Skip List）</strong>：在长倒排列表中插入跳表索引，方便快速跳过不需要的部分。</li><li><strong>布尔查询（Boolean Queries）</strong>：结合多个词条的倒排列表进行布尔运算（AND, OR, NOT），提升查询的组合能力。</li><li><strong>位置索引</strong>：记录词条在文档中的具体位置，以支持短语搜索或邻近搜索。</li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5879.%E4%BB%80%E4%B9%88%E6%98%AFElasticsearch%E7%9A%84PostingList%E5%80%92%E6%8E%92%E5%88%97%E8%A1%A8%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E5%8E%9F%E7%90%86%E9%9D%A2%E8%AF%95%E9%A2%98/5879.%E4%BB%80%E4%B9%88%E6%98%AFElasticsearch%E7%9A%84PostingList%E5%80%92%E6%8E%92%E5%88%97%E8%A1%A8%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="什么是-Elasticsearch-的-Posting-List-倒排列表？"><a href="#什么是-Elasticsearch-的-Posting-List-倒排列表？" class="headerlink" title="什么是]]>
    </summary>
    <title>什么是 Elasticsearch 的 Posting List 倒排列表？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch 评分面试题" scheme="https://javai.tech/categories/Elasticsearch-%E8%AF%84%E5%88%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch评分" scheme="https://javai.tech/tags/Elasticsearch%E8%AF%84%E5%88%86/"/>
    <content>
      <![CDATA[<h1 id="什么是-Elasticsearch-中的相关性得分？有哪些影响因素？"><a href="#什么是-Elasticsearch-中的相关性得分？有哪些影响因素？" class="headerlink" title="什么是 Elasticsearch 中的相关性得分？有哪些影响因素？"></a>什么是 Elasticsearch 中的相关性得分？有哪些影响因素？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch中的相关性得分（Relevance Score）是一个衡量文档与查询匹配程度的数值。简而言之，它表示搜索结果中每个文档的匹配程度，得分越高，表示文档与查询的相关性越强。这个得分主要由Lucene使用TF-IDF算法和BM25算法计算得出。</p><p>影响相关性得分的主要因素包括：<br>1）查询的类型及结构：例如，<code>match</code> 查询和 <code>term</code> 查询计算相关性得分的方式不同。<br>2）词频（TF，Term Frequency）：一个词在文档中出现的频率越高，该文档被认为和查询匹配的程度越高。<br>3）逆文档频率（IDF，Inverse Document Frequency）：一个词在整个索引中出现的频率越低，该词的区分度越高，得分贡献也就越大。<br>4）文档长度（Norms）：一般来说，短文档中的匹配关键词比长文档中的匹配关键词更有代表性。<br>5）字段的权重：可以通过<code>boost</code>参数给某些字段更高的权重，从而影响最终的得分。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）<strong>查询类型及权重调整</strong>：</p><ul><li>不同类型的查询会影响得分，比如<code>match</code>查询会对相关性进行计算，而<code>term</code>查询则主要用于精确匹配。</li><li>通过调整字段的<code>boost</code>参数，可以增加或减少某个字段在计算相关性得分时的权重。</li></ul><p>2）<strong>TF-IDF与BM25</strong>：</p><ul><li><strong>TF-IDF</strong>（词频-逆文档频率），主要基于一个词在文档中出现的频率以及在所有文档中出现的稀有程度。</li><li><strong>BM25</strong>，是TF-IDF的改进版本，BM25考虑了频率因素但对长文档有更好的处理能力，并且是可调参数，能够更好地适应不同场景。</li></ul><p>3）<strong>脚本打分</strong>：</p><ul><li>Elasticsearch允许使用自定义脚本来计算相关性得分。例如，在某些自定义需求下，我们可以使用Painless脚本语言来调整文档的得分。</li></ul><p>4）<strong>多功能查询</strong>：</p><ul><li>通过<code>function_score</code>查询，可以灵活地调整和组合各种得分计算方式，例如常数查询、函数衰减（如距离衰减）、字段值因子加权以及随机权重。</li></ul><p>5）<strong>调试相关性得分</strong>：</p><ul><li>使用<code>explain</code>参数可以详细解释Elasticsearch如何计算每个文档的相关性得分。这是调试和优化搜索功能的一个有力工具。</li></ul>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E8%AF%84%E5%88%86%E9%9D%A2%E8%AF%95%E9%A2%98/5783.%E4%BB%80%E4%B9%88%E6%98%AFElasticsearch%E4%B8%AD%E7%9A%84%E7%9B%B8%E5%85%B3%E6%80%A7%E5%BE%97%E5%88%86%EF%BC%9F%E6%9C%89%E5%93%AA%E4%BA%9B%E5%BD%B1%E5%93%8D%E5%9B%A0%E7%B4%A0%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E8%AF%84%E5%88%86%E9%9D%A2%E8%AF%95%E9%A2%98/5783.%E4%BB%80%E4%B9%88%E6%98%AFElasticsearch%E4%B8%AD%E7%9A%84%E7%9B%B8%E5%85%B3%E6%80%A7%E5%BE%97%E5%88%86%EF%BC%9F%E6%9C%89%E5%93%AA%E4%BA%9B%E5%BD%B1%E5%93%8D%E5%9B%A0%E7%B4%A0%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="什么是-Elasticsearch-中的相关性得分？有哪些影响因素？"><a href="#什么是-Elasticsearch-中的相关性得分？有哪些影响因素？" class="headerlink" title="什么是 Elasticsearch]]>
    </summary>
    <title>什么是 Elasticsearch 中的相关性得分？有哪些影响因素？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Sherwin.Wei</name>
    </author>
    <category term="ElasticSearch 面试题" scheme="https://javai.tech/categories/ElasticSearch-%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="面试" scheme="https://javai.tech/categories/%E9%9D%A2%E8%AF%95/"/>
    <category term="Elasticsearch 评分面试题" scheme="https://javai.tech/categories/Elasticsearch-%E8%AF%84%E5%88%86%E9%9D%A2%E8%AF%95%E9%A2%98/"/>
    <category term="Elasticsearch" scheme="https://javai.tech/tags/Elasticsearch/"/>
    <category term="Elasticsearch查询" scheme="https://javai.tech/tags/Elasticsearch%E6%9F%A5%E8%AF%A2/"/>
    <category term="Elasticsearch评分" scheme="https://javai.tech/tags/Elasticsearch%E8%AF%84%E5%88%86/"/>
    <content>
      <![CDATA[<h1 id="Elasticsearch-的评分算法是如何工作的？它基于哪些因素计算相关性得分？"><a href="#Elasticsearch-的评分算法是如何工作的？它基于哪些因素计算相关性得分？" class="headerlink" title="Elasticsearch 的评分算法是如何工作的？它基于哪些因素计算相关性得分？"></a>Elasticsearch 的评分算法是如何工作的？它基于哪些因素计算相关性得分？</h1><h2 id="回答重点"><a href="#回答重点" class="headerlink" title="回答重点"></a>回答重点</h2><p>Elasticsearch 的评分算法主要基于 BM25（Best Matching 25）算法，这是一种改进的 TF-IDF 算法。它通过计算每个文档和查询之间的相关性得分来排序结果。相关性得分基于以下几个主要因素：</p><p>1）TF（Term Frequency）：词频，某个词在文档中出现的次数。出现次数越多，该词对该文档的重要性越大。<br>2）IDF（Inverse Document Frequency）：逆文档频率，用于衡量一个词在所有文档中有多重要。出现频率越低，IDF 越高，反之亦然。<br>3）Field Length Norm（规范化字段长度）：字段的长度。一般来说，较短的字段如果包含查询词，那么该字段的相关性得分会更高。<br>4）Document Norms（文档规范化）：这是对文档多个字段进行规范化处理的一个综合得分。</p><p>总得来说，Elasticsearch 的评分算法即是通过这些因素来计算每个文档的相关性得分，并将得分高的文档返回给用户。</p><h2 id="扩展知识"><a href="#扩展知识" class="headerlink" title="扩展知识"></a>扩展知识</h2><p>1）理解 BM25：<br>BM25 是 BM 系列的其中一个成员，它有效地调整了传统的 TF-IDF 算法。例如，它包含参数 b 和 k1，用来调整词频和文档长度带来的影响。b 参数用于调节字段长度对评分的影响，k1 参数则用于调节 TF 的饱和水平。</p><p>2）Elasticsearch 的更多打分机制：<br>除了 BM25，Elasticsearch 还支持多种评分算法，比如标量场评分（Painless scripting）、无评分或固定评分等。根据需求的不同，您可以覆盖默认的 BM25 机制，使用自定义的脚本来计算相关性评分。</p><p>3）Boosting：<br>为了获取更精确的搜索结果，Elasticsearch 支持 boosting 功能，即为特定字段或查询添加权重。例如，可以增加标题字段的权重，使得在标题中出现的查询词比在正文中出现的关联性更高。</p><p>4）Explain API：<br>Elasticsearch 还提供了一个强大的 Explain API，它可以详细解释某个文档为何匹配某个查询，并且每个部分的相关性分数是如何计算的。这对于调试和优化查询非常有用。</p>]]>
    </content>
    <id>https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E8%AF%84%E5%88%86%E9%9D%A2%E8%AF%95%E9%A2%98/5845.Elasticsearch%E7%9A%84%E8%AF%84%E5%88%86%E7%AE%97%E6%B3%95%E6%98%AF%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%E7%9A%84%EF%BC%9F%E5%AE%83%E5%9F%BA%E4%BA%8E%E5%93%AA%E4%BA%9B%E5%9B%A0%E7%B4%A0%E8%AE%A1%E7%AE%97%E7%9B%B8%E5%85%B3%E6%80%A7%E5%BE%97%E5%88%86%EF%BC%9F/</id>
    <link href="https://javai.tech/2025/03/11/%E9%9D%A2%E8%AF%95/Elasticsearch%E8%AF%84%E5%88%86%E9%9D%A2%E8%AF%95%E9%A2%98/5845.Elasticsearch%E7%9A%84%E8%AF%84%E5%88%86%E7%AE%97%E6%B3%95%E6%98%AF%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%E7%9A%84%EF%BC%9F%E5%AE%83%E5%9F%BA%E4%BA%8E%E5%93%AA%E4%BA%9B%E5%9B%A0%E7%B4%A0%E8%AE%A1%E7%AE%97%E7%9B%B8%E5%85%B3%E6%80%A7%E5%BE%97%E5%88%86%EF%BC%9F/"/>
    <published>2025-03-10T16:01:03.000Z</published>
    <summary>
      <![CDATA[<h1 id="Elasticsearch-的评分算法是如何工作的？它基于哪些因素计算相关性得分？"><a href="#Elasticsearch-的评分算法是如何工作的？它基于哪些因素计算相关性得分？" class="headerlink"]]>
    </summary>
    <title>Elasticsearch 的评分算法是如何工作的？它基于哪些因素计算相关性得分？</title>
    <updated>2025-03-10T16:01:02.000Z</updated>
  </entry>
</feed>
