<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Han's 世界</title>
        <link>https://blog-orcin-five-66.vercel.app</link>
        <description>记录自己的当下</description>
        <lastBuildDate>Sat, 11 Apr 2026 09:32:40 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>Feed</generator>
        <language>zh-CN</language>
        <image>
            <title>Han's 世界</title>
            <url>https://blog-orcin-five-66.vercel.app/static/favicons/favicon.ico</url>
            <link>https://blog-orcin-five-66.vercel.app</link>
        </image>
        <copyright>CC BY-NC-SA 4.0</copyright>
        <item>
            <title><![CDATA[ES查询改造方案]]></title>
            <link>https://blog-orcin-five-66.vercel.app/blog/esqueryrenovationplan</link>
            <guid>https://blog-orcin-five-66.vercel.app/blog/esqueryrenovationplan</guid>
            <pubDate>Sun, 15 Jun 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[详细阐述查询数据源从MySql迁移到ES的完整改造过程]]></description>
            <content:encoded><![CDATA[<p>详细阐述查询数据源从MySql迁移到ES的完整改造过程</p> <hr> <p>为提升管理页面交易数据查询性能，由原先的MySql修改为ES作为数据存储中心进行查询。方案落地需要我们完成如下两点：</p>
<ol>
<li>MySql到ES之间的存量、实时数据同步</li>
<li>修改适配服务目前的查询逻辑，支持ES语法查询数据
而对于上面亮点的具体细化实现过程中不乏一些阻碍，下面我将会对完整的方案内容，以及方案落地过程中所遇到的阻碍和解决方案做具体的说明。目前该套方案已经在RHF-UAT环境中部署，通过SPMS4.0的交易流水查询页面即可进行体验。</li>
</ol>
<h1 id="一方案说明">一、方案说明</h1>
<p>目前使用Canal Server --> Canal Adapter的同步工具，将MySql中的数据同步到ES中，支持存量和实时同步。</p>
<pre><code>Canal-Deployer: 增量日志解析的中间件，通过伪装成MySql的从节点来获取binlog变更，解析为自己的消息格式后提供下游消费。
Canal-Adapter: 官方提供的数据适配器组件，是Canal Client的高级封装，用于消费Server端产生的数据变更消息，支持将数据变更消息同步至多种异构数据源中
Canal-Admin: 图形化管理后台，提供服务的在线配置监控等功能。
</code></pre>
<figure class="rehype-figure"><img src="/static/photos/EsQueryRenovationPlan/EsQueryRenovationPlan-20250611-2.png" alt=""></figure>
<pre><code>目前本套方案各个组件的版本说明 -- 基于RHF的当前生产版本
MySql: 8.0.34
Canal-Deployer:  1.1.8
Canal-Client:  1.1.8
Canl-Admin: 1.1.8
ES: 6.4.2
</code></pre>
<h1 id="二方案落地明细说明">二、方案落地明细说明</h1>
<h2 id="21-数据同步">2.1 数据同步</h2>
<p>将MySql中的数据同步至ES中，我们会需要解决如下几个问题：</p>
<ol>
<li>如何配置和使用Canal-Deployer、Canal-Adapter同步组件？</li>
<li>ES中的索引结构需要如何定义？定义成什么样？
下面将围绕上面问题进行详细说明</li>
</ol>
<h3 id="211-canal-deployer的配置使用">2.1.1 Canal-Deployer的配置使用</h3>
<h4 id="1-安装">1. 安装</h4>
<p>访问官方GitHub寻找对应版本，地址：<code>https://github.com/alibaba/canal/releases</code>，选择<code>canal.deployer-***.tar.gz</code>
解压命令：<code>tar -xzvf 文件名.tar.gz -C 目标目录</code></p>
<h4 id="2-配置">2. 配置</h4>
<p>我将先对Canal-Deployer的内部组件名词和之间的关系进行介绍，这将对配置更好的理解。</p>
<pre><code>Server: 当前的服务进程，一个Canal-Deployer代表一个Server，可以结合ZK进行集群部署
Instance(实例): 最小的工作单元(线程级别)，每个Instance对应一个独立的MySQL数据库binlog订阅通道，拥有独立的解析配置、过滤规则和消费逻辑，多个Instance之间互不影响，可并行运行
</code></pre>
<p>基于上面的两个概念，我们知道涉及主要两个配置文件：Server 和 Instance，下面我们以单服务端、单实例为背景来说明如何进行配置。<code>集群和多实例在单机单实例跑通了之后自己也就知道怎么配置了</code></p>
<ul>
<li>Server涉及的配置文件为: <code>canal.deployer-***/conf/canal.properties</code> ， 文件关键配置说明如下：(其余配置节点默认配置即可，下同)</li>
</ul>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">... </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># 服务的端口，客户端连接的端口</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.port</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> 11111</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># 实例名称 -- 多个实例使用「,」间隔 eg:example1,example2,...</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.destinations</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> example</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># canal admin config -- 管理后台的配置信息</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.admin.port</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> 11110 </span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.admin.user</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> admin</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># 密码 - 明文 SHA-1 后得到</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.admin.passwd</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> 4ACFE3202A5FF5CF467898FC58AAB1D615029441</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">... </span></span>
<span class="line"></span></code></pre>
<ul>
<li>Instance涉及的配置文件为: <code>canal.deployer-***/conf/实例名称/instance.properties</code>，文件关键配置说明如下：(如果需要创建不同的实例则在不同的实例文件名路径下创建对应的instance.properties配置文件即可)</li>
</ul>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># 配置需要监控的数据库地址，当数据库为主从架构时可以使用「,」间隔配置地址</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.instance.master.address</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">127.0.0.1:3308</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># 数据库账号、密码</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.instance.dbUsername</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">username</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.instance.dbPassword</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">password</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># 是否开启主库存活检测（默认false）当主从配置时开启使用</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.instance.detecting.enable</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">false</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># 配置需要监控的表，默认{.*\\..*}代表监控所有表的变动</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"># 语法规则 1.Java正则表达式​​:需注意转义(如.需写为\\.)2.两​级结构​:{schema正则}.{table正则}用点号分隔;3.大小写敏感: 取决于MySQL的lower_case_table_names参数</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.instance.filter.regex</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">webapi_insurance\.trans_record,webapi_insurance\.refund_trans_record,webapi_insurance\.trans_record_extension</span></span></code></pre>
<h4 id="3启动关闭">3.启动/关闭</h4>
<p>执行<code>canal.deployer-***/bin/</code>下的脚本，即可完成启动、关闭、重启的操作，具体的日志信息在<code>canal.deployer-***/logs/</code>下会进行打印</p>
<p>至此Canal的服务端搭建完毕可以正常使用，下面将说明客户端的配置使用。</p>
<h3 id="212-canal-adapter的配置使用">2.1.2 Canal-Adapter的配置使用</h3>
<h4 id="1-安装-1">1. 安装</h4>
<p>访问官方GitHub寻找对应版本，地址：<code>https://github.com/alibaba/canal/releases</code>，选择<code>canal.adapter-***.tar.gz</code>
解压命令：`tar -xzvf 文件名.tar.gz -C 目标目录
版本和deployer保持一致</p>
<h4 id="2配置">2.配置</h4>
<p>Adapter的配置目录结构如下，我们主要关心的配置有两个:<code>application.yml</code>和监听数据库表的配置，而表的配置需要在哪个ES文件下取决于我们同步目标的ES版本。</p>
<pre><code>- ...
- conf
  - application.yml
  - es6
    - {tableName}.yml
  - es7
  - es8
  - ...
</code></pre>
<p>下面我将对这两个部分的配置文件进行详细说明</p>
<ul>
<li><code>/canal.adapter-***/conf/application.yml</code> Canal-Adapter的核心配置文件</li>
</ul>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#E2931D;--shiki-dark:#FFCB6B">...</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">canal.conf</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">  mode</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> tcp</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # 使用tcp的方式连接</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">  # 失败重试次数 -1表示无限重试,重试间隔500ms</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">  retries</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> 3</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">  # 默认false，开启后在失败超过重试次数之后当前同步进程会被中断</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">  terminateOnException</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#FF5370;--shiki-dark:#FF9CAC"> true</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">  consumerProperties</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    # canal tcp consumer</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">    canal.tcp.server.host</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> 127.0.0.1:11111</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # canal服务端的ip:port 2.1.1中启动的服务</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">  # 配置需要监听的数据库的地址、账号、密码</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">  srcDataSources</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">    defaultDS</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">      url</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> jdbc:mysql://127.0.0.1:3308/webapi_insurance?characterEncoding=utf8</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">      username</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> dataname</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">      password</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> password</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    </span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">   canalAdapters</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    # 2.1.1中说明的创建的实例名称，这个名字需要特别注意和服务端的实例匹配，不然无法成功同步</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    -</span><span style="color:#E53935;--shiki-dark:#F07178"> instance</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> webapi4.0</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">      groups</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">      -</span><span style="color:#E53935;--shiki-dark:#F07178"> groupId</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> g1</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">        outerAdapters</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        # 需要与自己的es版本对上，6.*版本就写es6，7.*版本就写es7</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        -</span><span style="color:#E53935;--shiki-dark:#F07178"> name</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> es6</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">          # 数据同步目标的ES地址</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">          hosts</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> http://127.0.0.1:9200</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">          # 默认配置即可</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">          properties</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">            mode</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> rest</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # or rest</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">            security.auth</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> elastic:elastic</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">            cluster.name</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> my-es</span></span></code></pre>
<p>特别注意：</p>
<ol>
<li><code>retries: -1</code>: 这个是需要特别注意的一个配置，默认-1表示当数据同步异常时会无限重试。如果配置指定数字例如"3"，则表示重试3次之后如果还是没有成功会放弃本次数据变更的同步并对服务端进行ack，这将会到此本次数据变更永久丢失(对于同步目标来说)。同时，为了保证数据需要绝对一致的场景，官方提供了<code>terminateOnException: true</code>的配置用于开启当超出同步重试次数时，同步进程直接中断的功能。<code>详见源码：AdapterProcessor#219:233行</code>
中断影响域为<code>instance级别</code>，如过需要重新开启可以发起如下http请求:<code>http://127.0.0.1:8081/syncSwitch/{destination}/{status} 端口为Adpts的默认端口 destination-实例名称；status-开关状态off on</code> -- 额外提一句这里的开关源码里利用互斥实现，该实现基于Cocurrent中的AQS实现了自己的sync BooleanMutex<code>详见源码：SyncSwitch&#x26;&#x26;BooleanMutex</code></li>
<li><code>groups</code>和 <code>outerAdapters</code> 两个配置节点下都可以配置多个，他们处理的消息实例来源都是同一个。不同的是<code>groups</code>之间是独立线程互不影响，而<code>outerAdapters</code>下是在同一个线程中。使用场景可以为针对同一个数据源，需要将相同/不同的表数据使用不同的同步频率同步至不同的目标中，如实时数据高频同步至ES中，系统的操作信息数据低频的同步至HBase中。<code>详见源码：CanalAdapterLoader#54:91行</code></li>
<li><code>name: es6</code> 这个配置用于标识同步目标的具体信息，可以让程序清楚具体加载哪个处理器对数据进行同步(不同的目标的具体语法不同，如es6跟es7的语法就会有差异，Adapter源码中对不同结构的数据库继承接口<code>OuterAdapter</code>进行不同实现，从而使上层调用统一)。<code>具体的加载逻辑详见源码: CanalAdapterLoader#94:122行</code></li>
</ol>
<ul>
<li><code>/canal.adapter-***/conf/es6/{tablename}.yml</code>这里的具体写明es6，是因为我当前的同步目的数据库是ES6版本，所以这边以此为例展开对该配置文件的详细说明。</li>
</ul>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#E53935;--shiki-dark:#F07178">trans_record.yml配置文件说明</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#E2931D;--shiki-dark:#FFCB6B">...</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">dataSourceKey</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> defaultDS</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">destination</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> webapi4.0</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # 需要根据server端的instance名称决定</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">groupId</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> g1</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">esMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	_index</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> uat_webapi_all_trans_record</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # 需要根据索引名称决定</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	_type</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> _doc</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	_id</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">id</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # 唯一键</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	upsert</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#FF5370;--shiki-dark:#FF9CAC"> true</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # id存在则更新，否则插入</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	sql</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> SELECT</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">		concat('webapit', record.id) AS id,</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">		'</span><span style="color:#91B859;--shiki-dark:#C3E88D">3</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">'</span><span style="color:#91B859;--shiki-dark:#C3E88D"> AS 'system',</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">		record.enterprise_num AS entNum,</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">		COALESCE(record.mch_id, '') AS fgMchCode,</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">		DATE_FORMAT(ext.notify_finish_time, '%Y-%m-%d %H:%i:%s') AS notifyFinishTime,</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">		FROM trans_record record left join trans_record_extension ext ON record.fg_trade_no = ext.fg_trade_no AND record.enterprise_num = ext.enterprise_num</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">		etlCondition</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">where record.orderCreateTime>={}</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # 批量同步时的条件</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	commitBatch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> 3000</span></span>
<span class="line"></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">refund_trans_record.yml配置文件说明:(除了sql不同其余都和上述一致)</span></span>
<span class="line"><span style="color:#E2931D;--shiki-dark:#FFCB6B">...</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">dataSourceKey</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> defaultDS</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">destination</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> webapi4.0</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # 需要根据server端的instance名称决定</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">groupId</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> g1</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">esMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	_index</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> uat_webapi_all_trans_record</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> # 需要根据实际的索引名称决定</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	_type</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> _doc</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	_id</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">id</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	pk</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">id</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	upsert</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#FF5370;--shiki-dark:#FF9CAC"> true</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	sql</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#91B859;--shiki-dark:#C3E88D"> select</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">	concat('webapir', rtr.id) as id,</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">	rtr.refund_no as outRefundNo,</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">	COALESCE(record.fg_fee_settle, '0') AS fgFeeSettle,</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">	DATE_FORMAT(ext.shipping_confirm_receive_time, '%Y-%m-%d %H:%i:%s') AS shippingConfirmReceiveTime</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">	from refund_trans_record rtr left join trans_record record</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">	on rtr.fg_trade_no = record.fg_trade_no and rtr.enterprise_num = record.enterprise_num</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">	left join trans_record_extension ext</span></span>
<span class="line"><span style="color:#91B859;--shiki-dark:#C3E88D">	on rtr.fg_trade_no = ext.fg_trade_no and rtr.enterprise_num = ext.enterprise_num</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	etlCondition</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">where rtr.orderCreateTime>={}</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span></span>
<span class="line"><span style="color:#E53935;--shiki-dark:#F07178">	commitBatch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> 3000</span></span></code></pre>
<p>该部分中，遇到最大的问题是：</p>
<ol>
<li>需要同步trans_record、refund_trans_record、trans_extend三张表，它们之间的关系为trans_record:refund_trans_record = 1:N ; trans_record:trans_extend = 1:1;</li>
<li>数据在ES中的是以tran_record为基准与余下的两张表通过关联展开方式存储在一个索引结构中，即存在一条交易T1，对应两天退款R1、R2以及一条扩展信息E1，那么同步后ES索引下会有三条记录，分别是<code>记录A: T1 E1</code>、<code>记录B: T1 R1 E1</code> 、<code>记录C: T1 R2 E1</code>，其中为了保证记录的id唯一，我们假定设置记录id为<code>记录A: T1.id</code>、<code>记录B: R1.id</code>、<code>记录C: R2.id</code>(目前的方案中也是这么做的)
ES的数据维护，如更新删除等都会基于记录id来定位实现。对于上述的同步需求，当T1记录存在数据更新的时候，需要同时更新三条条记录，但是对于当前canal来说，binlog日志中只会存在交易记录T1的数据信息，不会有其它表的信息如R1或R2的id信息，<strong>这将会导致对于连表查询下数据无法同步问题</strong>(需要特别说明的是，普通的连表是1:N关系下只有N条记录，而当前是N+1条记录)。
对于这个问题在Canal-Adapter中的做法是：</li>
<li>同时配置<code>trans_record.yml</code>、<code>refund_trans_record.yml</code>两张表的同步配置，<code>trans_record.yml</code>只对交易数据进行同步，<code>refund_trans_record.yml</code>对退款和交易的关联查询数据进行同步。</li>
<li>Canal-Adapter在对<code>{tablename}.yml</code>配置文件加载时，会解析其中的sql语句，获取字段映射关系(mysql与es之间)等配置信息，并<strong>关以sql中的所有表名称作为key独立保存当前配置</strong></li>
<li>当监听到Instance的数据变更消息时，Canal-Adapte会通过表名去匹配遍历执行所有命中的配置，并通过配置中的sql语句查询数据源，根据查询出来的数据即可完成批量的更新操作。例如: 当<code>refund_trans_record</code>表数据变更时，只有<code>refund_trans_record.yml</code>文件中的配置会被执行，并完成对两条退款记录的更新操作。当<code>trans_record</code>表数据变更时，会执行<code>trans_record.yml</code>和<code>refund_trans_record.yml</code>两个配置，并完成三条记录的更新操作，因为这两个配置文件的sql都存在表<code>trans_record</code>。
<code>配置加载源码:ESAdapter#addSyncConfigToCache() -- dbTableEsSyncConfig变量; 遍历执行源码: ESAdapter#sync() -- configMap变量是一个Map</code>
Canal-Adapter的做法很巧妙的解决的这种复杂连表下的数据批量更新问题(刚看官方文档和源码的时候还以为这种连表的批量更新不支持，还专门改了下源码自己扩展了下，没想到是自己没有看明白)，同样的对于<code>trans_extend</code>表的更新也是如此理解。</li>
</ol>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span>数据批量同步的时候请求http地址:http://127.0.0.1:8081/etl/{type}/{task}?params=param1,param2</span></span>
<span class="line"><span>type – 类型 hbase, es </span></span>
<span class="line"><span>task – 任务名对应配置文件名 mytest_person2.yml </span></span>
<span class="line"><span>params – etl where条件参数-配置文件中的etlCondition节点, 为空全部导入。参数需要和配置条件保持一致</span></span></code></pre>
<h4 id="3启动关闭-1">3.启动/关闭</h4>
<p>执行<code>canal.adapter-***/bin/</code>下的脚本，即可完成启动、关闭、重启的操作，具体的日志信息在<code>canal.adapter-***/logs/</code>下会进行打印
至此Canal的客户端搭建完毕可以正常使用</p>
<h3 id="213-canal-admin的配置使用">2.1.3 Canal-Admin的配置使用</h3>
<p>admin管理后台的使用配置比较开箱即用，Github目录下有对应的下载，配置下application.yml的数据库连接信息即可启动，启动脚本也在bin目录下。
对于Canal-Deployer服务端也只需要简单的修改对应路径下<code>canal-deployer.*/conf/canal.properties</code>配置文件即可，涉及的配置节点如下: (上文2.1.1中介绍canal.properties的配置文件时也有过说明)</p>
<pre><code class="language-properites">canal.admin.manager = 127.0.0.1:8089
canal.admin.port = 11110
canal.admin.user = admin
canal.admin.passwd = 2091729fef5380984e869b8c254c7283ecab23f9
</code></pre>
<p>admin并不是迁移过程中核心必备的组件，只不过可以让服务端管理更友好，更多的内容官方文档也有介绍，这里不进行过多的赘述。</p>
<h3 id="214-es的索引字段配置">2.1.4 ES的索引字段配置</h3>
<p>通过es命令执行创建对应的索引结构，内容如下:</p>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">{</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">  "</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">settings</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    "</span><span style="color:#E2931D;--shiki-dark:#FFCB6B">number_of_shards</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> 1</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    "</span><span style="color:#E2931D;--shiki-dark:#FFCB6B">number_of_replicas</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> 0</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    "</span><span style="color:#E2931D;--shiki-dark:#FFCB6B">refresh_interval</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">30</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">  },</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">  "</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">mappings</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    "</span><span style="color:#E2931D;--shiki-dark:#FFCB6B">_doc</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">      "</span><span style="color:#F76D47;--shiki-dark:#F78C6C">properties</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        "</span><span style="color:#E53935;--shiki-dark:#F07178">id</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            "</span><span style="color:#916B53;--shiki-dark:#916B53">type</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">keyword</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        },</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        "</span><span style="color:#E53935;--shiki-dark:#F07178">refundRealRefundAmount</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            "</span><span style="color:#916B53;--shiki-dark:#916B53">type</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">scaled_float</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            "</span><span style="color:#916B53;--shiki-dark:#916B53">scaling_factor</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> 100</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        },</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        "</span><span style="color:#E53935;--shiki-dark:#F07178">refundRefundChannel</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            "</span><span style="color:#916B53;--shiki-dark:#916B53">type</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">keyword</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        },</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        "</span><span style="color:#E53935;--shiki-dark:#F07178">shippingConfirmReceiveTime</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            "</span><span style="color:#916B53;--shiki-dark:#916B53">type</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">date</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            "</span><span style="color:#916B53;--shiki-dark:#916B53">format</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">strict_date_optional_time||epoch_millis</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">      }</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">  }</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span></code></pre>
<p>这个部分的工作难度并不高，但比较繁琐，因为需要将数据库字段与ES中的字段一一对应以及定义合适的数据类型(目前整理的es字段有100个)，目前我选用的类型有三种: keyword、scaled_float、date分别用于文本、金额、时间三个类型场景，覆盖了当前的界面查询条件需求。
对于索引结构创建需要注意的点是:</p>
<ol>
<li><code>number_of_shards</code>和<code>number_of_replicas</code>需要分别设置为1和0，让数据在同一个节点中保存，可以防止查询时出现数据失真的情况(多个分片下聚合查询下TopN的问题)。而对于可能的数据丢失风险，因为我们目前使用的场景是界面查询使用的备库使用，所以就算极端情况下丢失也还能从数据库中恢复回来。</li>
<li><code>refresh_interval</code>表示数据的刷新时间，时间越小资源消耗越高。建议当首次批量同步时挑大一点例如30s，实时同步时可以小一点例如5s。</li>
</ol>
<h2 id="22-数据查询">2.2 数据查询</h2>
<p>当完成数据的同步后，剩下的就需要考虑如何解决将原来代码中的查询MySQL的逻辑修改为查询ES，且代码的改动幅度需要尽可能的小。目前需要改造的项目Adpts是一个多数据源，提供组内不同产品的统一查询服务，项目对查询Mapper层做了抽象和封装，统一的入参Req和返回对象Resp，不同产品间自己进行独立的实现。本次我们Es的查询方案只涉及其中一个产品，基于现有的代码分层我们只需要修改其中一个Mapper层即可。虽然代码的层级架构设计，让我们可以很好的控制代码修改范围，但是如何保持入参和返回对象一致是一个有挑战的事情。这里涉及两个困难点：</p>
<ol>
<li>如何将入参转为ES的查询条件语法？</li>
<li>如何将ES的查询结果映射为返回对象？
代码需要考虑：健壮性、可维护性以及可扩展性；基于以上问题点以及希望达成的目标，下面笔者将通过文字以及部分核心伪代码来对当前的解决方案做详细陈述。</li>
</ol>
<h3 id="221-查询参数转为es查询语法">2.2.1 查询参数转为ES查询语法</h3>
<p>对于完成Java实体查询参数转为ES查询请求这一需求，我们首先需要了解的是ES的查询语法在Java中是如何进行编写的。下面我将先通过使用示例对ES的查询语法使用做简单的说明。</p>
<h4 id="2211-java中es的查询使用">2.2.1.1 Java中ES的查询使用</h4>
<ol>
<li>使用的es客户端为：<code>Rest High Level Client</code>，对应的pom引入如下 -- 版本号与ES服务保持一致。至于选择该客户端的理由我在下面附件罗列目前了几种主流的客户端优缺点比对图</li>
</ol>
<pre><code class="language-pom">&#x3C;dependency>  
    &#x3C;groupId>org.elasticsearch.client&#x3C;/groupId>  
    &#x3C;artifactId>elasticsearch-rest-high-level-client&#x3C;/artifactId>  
    &#x3C;version>6.4.2&#x3C;/version> &#x3C;!-- 严格匹配ES版本 -->  
&#x3C;/dependency>  
  
&#x3C;!-- 需要显式声明以下依赖以避免冲突 -->  
&#x3C;dependency>  
    &#x3C;groupId>org.elasticsearch&#x3C;/groupId>  
    &#x3C;artifactId>elasticsearch&#x3C;/artifactId>  
    &#x3C;version>6.4.2&#x3C;/version>  
&#x3C;/dependency>
</code></pre>
<ol start="2">
<li>使用示例</li>
</ol>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esIndex </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">uat_webapi_all_trans_record</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> allParamQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// should - 或</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> shouldQeury </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">shouldQeury</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">should</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">es_field_name</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">queryParam</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 带「*」表示模糊查询</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">shouldQeury</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">should</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">es_field_name2</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">*queryParam2*</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 至少需要匹配一个  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">shouldQeury</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">minimumShouldMatch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#F76D47;--shiki-dark:#F78C6C">1</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">allParamQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">shouldBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">shouldQeury</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// mustNot - 不等于</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">QueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> mustNotQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">es_field_name3</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">queryParam3</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">allParamQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">mustNot</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">mustNotQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// must - 等于</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">QueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> mustQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">es_field_name4</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">queryParam4</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">allParamQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">must</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">mustQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">SearchSourceBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> sourceBuilder </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> SearchSourceBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        .</span><span style="color:#6182B8;--shiki-dark:#82AAFF">query</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">allParamQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        .</span><span style="color:#6182B8;--shiki-dark:#82AAFF">from</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#F76D47;--shiki-dark:#F78C6C">0</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> // 起始行  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        .</span><span style="color:#6182B8;--shiki-dark:#82AAFF">size</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#F76D47;--shiki-dark:#F78C6C">50</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> // 本次查询数量，结合from参数实现分页效果</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        .</span><span style="color:#6182B8;--shiki-dark:#82AAFF">sort</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">es_field_name</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">desc</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> // 根据es_field_name字段降序</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 实际中使用searchAfter的方式进行翻页查询，解决深度分页查询下性能问题    </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">//        .query(allParamQuery)  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">//        .searchAfter(esSearchAfter)</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">//        .size(50) // 本次查询数量，结合from参数实现分页效果</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">//        .sort("es_field_name", "desc"); // 根据es_field_name字段降序</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">//        // 固定排序条件 - 防止翻页时的乱序  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">//		.sort("id", SortOrder.ASC);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 组装查询请求</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">SearchRequest</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> searchRequest </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> SearchRequest</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esIndex</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">searchRequest</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">source</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">sourceBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 发起查询</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">SearchResponse</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> response </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> restHighLevelClient</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">search</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">searchRequest</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> RequestOptions</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">DEFAULT</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 获取查询结果，Map中的key:es的字段名称，value:字段对应的内容; List代表每行记录</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">>></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> results </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> ArrayList</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;>();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">for</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">SearchHit</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> hit </span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> response</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getHits</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">())</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    results</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">add</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">hit</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getSourceAsMap</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> results</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span></span></code></pre>
<p>上述伪代码对应的sql以及ES6原生查询请求分别如下:</p>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#F76D47;--shiki-dark:#F78C6C">select</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> *</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> from</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> table</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> where</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> (es_field_name </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> '</span><span style="color:#91B859;--shiki-dark:#C3E88D">queryParam</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">'</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> or</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> es_field_name2 </span><span style="color:#F76D47;--shiki-dark:#F78C6C">like</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> '</span><span style="color:#91B859;--shiki-dark:#C3E88D">%queryParam2%</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">'</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">) </span><span style="color:#F76D47;--shiki-dark:#F78C6C">and</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> es_field_name3 </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">!=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> '</span><span style="color:#91B859;--shiki-dark:#C3E88D">queryParam3</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">'</span><span style="color:#F76D47;--shiki-dark:#F78C6C"> and</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> es_field_name4 </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> '</span><span style="color:#91B859;--shiki-dark:#C3E88D">queryParam4</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">'</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">;</span></span></code></pre>
<pre><code class="language-es">{
  "from": 0,
  "size": 50,
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "es_field_name": "queryParam"
          }
        },
        {
          "term": {
            "es_field_name2": "*queryParam2*"
          }
        }
      ],
      "minimum_should_match": 1,
      "must_not": [
        {
          "term": {
            "es_field_name3": "queryParam3"
          }
        }
      ],
	  "must": [
		{
		  "term": {
			"es_field_name4": "queryParam4"
		  }
		}
	  ]
    }
  },
  "sort": [
    {
      "es_field_name": {
        "order": "desc"
      }
    }
  ]
}

</code></pre>
<h4 id="2212-复杂查询的转化解决方案">2.2.1.2 复杂查询的转化解决方案</h4>
<p>通过上述的伪代码，可以比较清晰的了解Java中如何进行es的查询操作方式，但是对于实际情况来说是复杂的，主要有如下几点：</p>
<ol>
<li>查询参数中属性的类型多样以及ES的字段格式多样，对应条件的查询需要保持一致。例如：查询属性的格式是yyyyMMdd的String类型，而它对应的ES查询字段是时间格式，直接查询会导致查询报错；</li>
<li>查询条件不仅限于等于、不等于，还存在范围查询，如: 大于、小于、模糊匹配等。</li>
<li>存在同一个查询属性同于用于两个ES字段，例如: <code>(field_name1 = 'param' or field_name2 = 'param')</code></li>
<li>需要支持参数为Collect类型时转为多值查询，例如：<code>field_name1 in ('param1', 'param2')</code></li>
<li>存在根据查询参数不同的值，来做不同的查询逻辑处理，例如：</li>
</ol>
<pre><code class="language-MyBatis">&#x3C;choose>  
    &#x3C;when test="param.allocationFlag == '0'.toString()">  
        and (ALLOCATIONFLAG is null or ALLOCATIONFLAG = '0')  
    &#x3C;/when>  
    &#x3C;otherwise>  
        and ALLOCATIONFLAG = #{param.allocationFlag, jdbcType=VARCHAR}  
    &#x3C;/otherwise>  
&#x3C;/choose>
</code></pre>
<ol start="6">
<li>查询参数中属性名称与ES中的字段名称不一致，导致ES请求中无从得知查询的字段名，例如：查询参数属性名<code>paramName</code>，需要查询的ES字段名<code>es_field_name</code></li>
</ol>
<p>通过对场景的分析提取，可以大致的将转化需要的信息分: ES查询的字段名、查询条件、查询关系、查询类型。因此可以得到<strong>解决方案的整体思路为：</strong></p>
<ol>
<li>通过在参数参数的属性字段上标注对应的注解，注解中表明字段对应的ES字段名、查询条件等信息。</li>
<li>在Mapper层中先对查询参数对象，通过反射方式获取对应的具体查询参数信息，例如：需要查询哪些ES的字段名、每个字段的查询条件、字段的查询关系、字段的查询类型等信息</li>
<li>根据获取到的信息按照ES的查询语法，逐个转化为对应的ES查询逻辑。(如上述的示例所示)
下面将通过部分核心伪代码尽可能的展示实现思路</li>
</ol>
<h5 id="2211-注解的定义">2.2.1.1 注解的定义</h5>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Target</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ElementType</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">FIELD</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Retention</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">RetentionPolicy</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">RUNTIME</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Documented</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> @</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">interface</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> EsFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 用于标记字段是否需要忽略处理</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    boolean</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> ignoreFlag</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> false;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 对应需要查询的es字段名称 默认使用属性名</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    String</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> name</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> ""</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 查询关系</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    JudgingConditionEnum</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> condition</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> JudgingConditionEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">MUST</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 当查询逻辑为或的时候，可以配置关联字段  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">[]</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> relatedConditions</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {};</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 查询类型</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    EsQueryTypeEnum</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> queryType</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> EsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ACCURATE</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 查询关系</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> enum</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> JudgingConditionEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    MUST</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">1</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">并</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    SHOULD</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">2</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">或</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    MUST_NOT</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">3</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">不包含</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 查询类型</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> enum</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> EsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    SPECIAL</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">0</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">特殊处理，需要自己写一个扩展方法</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    ACCURATE</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">1</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">精确</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    VAGUE</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">2</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">模糊</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    RANGE_GT</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">3</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">范围></span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    RANGE_GTE</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">4</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">范围>=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    RANGE_LT</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">5</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">范围&#x3C;</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    RANGE_LTE</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">6</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">范围&#x3C;=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">eg：</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">EsFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#E2931D;--shiki-dark:#FFCB6B">name</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">outTradeNo</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> condition</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> JudgingConditionEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">SHOULD</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> relatedConditions</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">exchangeNo</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">})</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> outTradeNoList</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">对应的sql</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">outTradeNo </span><span style="color:#6182B8;--shiki-dark:#82AAFF">in</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">''</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> or exchangeNo </span><span style="color:#6182B8;--shiki-dark:#82AAFF">in</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">''</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span></span></code></pre>
<h5 id="2212-保存通过反射获取的参数信息实体类">2.2.1.2 保存通过反射获取的参数信息实体类</h5>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Getter</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Setter</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> class</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> ESQueryParam</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     * es字段名称  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     * 条件内容  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryContent</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     * 判断条件  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> JudgingConditionEnum</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> judgingConditionEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     * 多字段查询时的关联字段  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">[]</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> relatedConditions</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     * 查询类型  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> EsQueryTypeEnum</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">/**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * 获取属性上的所有注解信息</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> *  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * </span><span style="color:#F76D47;font-style:italic;--shiki-dark:#F78C6C;--shiki-dark-font-style:italic">@param</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> object</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> 目标对象  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * </span><span style="color:#F76D47;font-style:italic;--shiki-dark:#F78C6C;--shiki-dark-font-style:italic">@return</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> 包装后的查询所需内容  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> */</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ESQueryParam</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#6182B8;--shiki-dark:#82AAFF"> getFieldAnnotations</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Object</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> object</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">	 // 反射解析逻辑，将统一的查询请求参数object转为内部自定义的ES查询信息参数</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">	 // 解析逻辑比较常规 就是一个注解解析过程 这边就不详细说明</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     // ... </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span></code></pre>
<h5 id="2213-es语法的转换逻辑">2.2.1.3 ES语法的转换逻辑</h5>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">/**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * 将查询参数转化为es的查询语法  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> BoolQueryBuilder</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> buildQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ESQueryParam</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> params</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> boolQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    for</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">ESQueryParam</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param </span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> params</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getEsFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        // 根据枚举类型添加到 BoolQuery 中  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        switch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getJudgingConditionEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">())</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            case</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> SHOULD</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">must</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">builderShouldQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">                break</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            case</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> MUST_NOT</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">mustNot</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">initBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">                break</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            default:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">                // 默认使用and  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">must</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">initBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 当should的查询类型时需要进行特殊构建  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> BoolQueryBuilder</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> builderShouldQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> ESQueryParam</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> shouldQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">().</span><span style="color:#6182B8;--shiki-dark:#82AAFF">should</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">initBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    for</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> condition </span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getRelatedConditions</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">())</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        shouldQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">should</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">initBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">condition</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 至少需要匹配一个  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    shouldQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">minimumShouldMatch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#F76D47;--shiki-dark:#F78C6C">1</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> shouldQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> QueryBuilder</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> initBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> ESQueryParam</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 如果是特殊构造的 就直接走特殊构造逻辑了  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">EsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">SPECIAL</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getEsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">fieldSpecialBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    return</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">initBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getQueryContent</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getEsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> </span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 对不同的查询类型进行单独构造</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> QueryBuilder</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> initBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> content</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> EsQueryTypeEnum</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    QueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">content </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">instanceof</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> Collection</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        queryBuilder </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termsQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> ((</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Collection</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">?</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">>)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> content</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">).</span><span style="color:#6182B8;--shiki-dark:#82AAFF">toArray</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">EsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">RANGE_GT</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        queryBuilder </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">rangeQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">).</span><span style="color:#6182B8;--shiki-dark:#82AAFF">gt</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">content</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">EsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">RANGE_GTE</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        queryBuilder </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">rangeQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">).</span><span style="color:#6182B8;--shiki-dark:#82AAFF">gte</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">content</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">EsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">RANGE_LT</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        queryBuilder </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">rangeQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">).</span><span style="color:#6182B8;--shiki-dark:#82AAFF">lt</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">content</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">EsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">RANGE_LTE</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        queryBuilder </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">rangeQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">).</span><span style="color:#6182B8;--shiki-dark:#82AAFF">lte</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">content</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> contentTemp </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">valueOf</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">content</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">EsQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">VAGUE</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esQueryTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        // 通过前后  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        contentTemp </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">format</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">*%s*</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> contentTemp</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    queryBuilder </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> contentTemp</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">/**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * 字段特殊性 - 这边优雅点的话可以类似结果映射中的typeHandler方式，但介于目前需要特殊处理的字段比较少，这边直接进行判断编写  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> QueryBuilder</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> fieldSpecialBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> ESQueryParam</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">allocationFlag</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> contentTemp </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">valueOf</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getQueryContent</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">0</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">contentTemp</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> boolQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">initEmptyBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">should</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">0</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> contentTemp</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">liquidationStatus</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">?</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> contentTemp </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> ((</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">?</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">>)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getQueryContent</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">contentTemp</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">contains</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">0</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> boolQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">initEmptyBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">should</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termsQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> contentTemp</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">toArray</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> contentTemp</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">toArray</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    log</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">error</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">【特殊处理异常】当前字段:{}配置了特殊处理，但是没有实际的处理逻辑，请检查</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    throw</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> RuntimeException</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">特殊处理异常，请检查</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">/**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * 查询字段内容是否为空的请求构造 -- es字段为空的查询需要多个条件判断所以这边进行了统一的封装</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> BoolQueryBuilder</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> initEmptyBuilder</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> boolQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">should</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">termQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> ""</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> notExistsQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">().</span><span style="color:#6182B8;--shiki-dark:#82AAFF">mustNot</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">QueryBuilders</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">existsQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">should</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">notExistsQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">minimumShouldMatch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#F76D47;--shiki-dark:#F78C6C">1</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">    return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> boolQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span></code></pre>
<h5 id="2214-使用方式">2.2.1.4 使用方式</h5>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 原来的查询参数参数</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">QueryParam</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> param </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> QueryParam</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 通过一行代码即可完成 现有的查询参数实体到ES查询实体的转化</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">BoolQueryBuilder</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> buildQuery </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> buildQuery</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getFieldAnnotations</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">param</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span></span></code></pre>
<p>上述内容完整的陈述了查询请求的改造方案，下面将对返回结果进行详细陈述</p>
<h3 id="222-返回结果映射为实体对象">2.2.2 返回结果映射为实体对象</h3>
<p>从上述中的Java中ES查询的简单示例可以看到，ES查询返回的内容格式为<code>List&#x3C;Map&#x3C;String, String>></code>格式对象，<code>Map中的key:es的字段名称，value:字段对应的内容; List代表每行记录</code>。与查询条件转化类似，在结果转化中遇到的主要问题如下：</p>
<ol>
<li>两边字段名称，数据类型格式不一致(主要为日期格式以及金额格式)</li>
<li>数据本身是加密存储的，查询的时候需要进行解密(原有的查询逻辑中是通过注解+切面的方式进行)
那么对此，我的解决方案思路为：</li>
<li>创建注解，对字段名称不一致，数据类型格式不一致的字段进行标记。由于不同的格式转换处理逻辑不一致，在注解中指定具体的转化执行类</li>
<li>使用原有的加密注解，对识别到有解密注解的字段调用解密逻辑
同样的，我将通过核心伪代码的方式对实现方案进行具体的展示</li>
</ol>
<h4 id="2221-字段映射注解">2.2.2.1 字段映射注解</h4>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Target</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ElementType</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">FIELD</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Retention</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">RetentionPolicy</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">RUNTIME</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Documented</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> @</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">interface</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> EsValueMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // es字段名称 为空默认与属性名称一致</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    String</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> esFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> ""</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 具体的转化执行类 默认类不做任何处理</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    Class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">?</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> extends ValueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#6182B8;--shiki-dark:#82AAFF"> convertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> BaseConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 时间字段需要转化的格式  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    String</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> srcFormat</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">yyyyMMddHHmmss</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 一些字符串的特殊处理类型 - 用于同一个执行类下进行不同处理逻辑使用</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    StrFormatTypeEnum</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> formatType</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> default</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> StrFormatTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">Default</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> enum</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> StrFormatTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    Default</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">0</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">无意义</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">  // 注解中必须要有一个默认值</span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    AmountDeal</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">1</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">es是金额格式，java是string</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">),</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    DateFormat</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">2</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> "</span><span style="color:#91B859;--shiki-dark:#C3E88D">es是ISO8601格式，java是string yyyyMMddHHmmss格式</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span></code></pre>
<h4 id="2222-核心转化类">2.2.2.2 核心转化类</h4>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Slf4j</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Service</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> class</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> AutoMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">?</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">>,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> ValueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> convertHandleMap </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> HashMap</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;>();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">?</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">>,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaObjectMap </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> HashMap</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;>();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    @</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Autowired</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#E2931D;--shiki-dark:#FFCB6B">required</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> false)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> IFingardDataEncryptSpec</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> iFingardDataEncryptSpec</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 调用入口 - 多行数据</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    public</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> &#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#6182B8;--shiki-dark:#82AAFF"> mapToBean</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">>></span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> maps</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> tClass</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        try</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> results </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> ArrayList</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;>();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            for</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> map </span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> maps</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                results</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">add</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">mapToBean</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> tClass</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> results</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> catch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Exception</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> ex</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            log</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">error</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">结果转换异常，异常原因:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> ex</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            throw</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> RuntimeException</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ex</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">	</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">	// 调用入口 - 单行数据</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    public</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> &#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> T</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> mapToBean</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> clazz</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        try</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            T</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> bean </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> clazz</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">newInstance</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            MetaObject</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaObject </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getAndCacheMetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">clazz</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            for</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">MetaField</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaField </span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getFields</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">())</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">().</span><span style="color:#6182B8;--shiki-dark:#82AAFF">set</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">bean</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">convertValueByAno</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> bean</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> catch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Exception</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> e</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            throw</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> RuntimeException</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">Map转对象失败</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> e</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">    </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    // 转化处理</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> convertValueByAno</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">MetaField</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        Object</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esValue </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> map</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">get</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getEsFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        // iFingardDataEncryptSpec 为空说明当前的配置没有开启加密  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">isEncryptFlag</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> &#x26;&#x26;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esValue </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">!=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> &#x26;&#x26;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> iFingardDataEncryptSpec </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">!=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">            // 目前加密的字段都是字符串字段  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            esValue </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> iFingardDataEncryptSpec</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">decrypt</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(null,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">valueOf</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esValue</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        esValue </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getValueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">().</span><span style="color:#6182B8;--shiki-dark:#82AAFF">convert</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esValue</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esValue</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    /**</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    * 获取转化需要的信息 - 通过缓存的方式实现性能的提升</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    **/</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> &#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> MetaObject</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> getAndCacheMetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> clazz</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        MetaObject</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaObject </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaObjectMap</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">get</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">clazz</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">metaObject </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">!=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        metaObject </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">clazz</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        metaObjectMap</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">put</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">clazz</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">/**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * Map转Bean多过程的信息类  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * 包括目标Bean中属性转化的处理类、对应的ES字段名称、格式类型等信息</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">   </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * </span><span style="color:#F76D47;font-style:italic;--shiki-dark:#F78C6C;--shiki-dark-font-style:italic">@author</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> Han  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> * </span><span style="color:#F76D47;font-style:italic;--shiki-dark:#F78C6C;--shiki-dark-font-style:italic">@version</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> 1.0 2025/06/04  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic"> **/</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Slf4j</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Getter</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Setter</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> class</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">    /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     * 字段本身  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">     */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">MetaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> fields </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> ArrayList</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;>();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    public</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> &#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#6182B8;--shiki-dark:#82AAFF"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> ctl</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#6182B8;--shiki-dark:#82AAFF">        initMetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ctl</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> &#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> void</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> initMetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">T</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> ctl</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        for</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Field</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field </span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">:</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> ctl</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getDeclaredFields</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">())</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            fields</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">add</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(this.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">initMetaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">));</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> MetaField</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> initMetaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Field</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        try</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            MetaField</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaField </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> MetaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">setAccessible</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(true);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">setField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">setEncryptFlag</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getAnnotation</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">EncryptField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> !=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esFieldName </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            ValueConvertHandle</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> valueConvertHandle </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> BaseConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            EsValueMapping</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esValueMapping </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getAnnotation</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">EsValueMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esValueMapping </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">!=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                esFieldName </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> StringUtils</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">isBlank</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esValueMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">esFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">())</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> ?</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> :</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esValueMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">esFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                valueConvertHandle </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esValueMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">convertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">().</span><span style="color:#6182B8;--shiki-dark:#82AAFF">newInstance</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">();</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">setDateFormat</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esValueMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">srcFormat</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">                metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">setStrFormatTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esValueMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">formatType</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">            }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">setEsFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">esFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">setValueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">valueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> catch</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Exception</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> ex</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">            log</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">error</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">对象反射解析处理异常，异常原因:</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> ex</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            throw</span><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic"> new</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> RuntimeException</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ex</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    @</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Getter</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    @</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Setter</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> static</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> class</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> MetaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Field</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> field</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         * 加密字段标记 true-加密 false-解密  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> boolean</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> encryptFlag</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         * 该字段在es中映射的名称，默认与属性名称一致 - 用于字段名称与es的字段名称不一致的情况下使用  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> esFieldName</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         * es数据源的字段类型  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> ValueConvertHandle</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> valueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         * 时间字段时需要转化为的格式 默认为:yyyyMMddHHmmss  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">        </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> String</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> dateFormat</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">        /**  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         * 字符串转字符串的不同处理  </span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">         */</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> StrFormatTypeEnum</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> strFormatTypeEnum</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span></code></pre>
<h4 id="2223-字段映射及格式处理类">2.2.2.3 字段映射及格式处理类</h4>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> interface</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> ValueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    Object</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> convert</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Object</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> inputOb</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">MetaField</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 字符串类型转为时间格式</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> class</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> StringToDateConvertHandle</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> implements</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> ValueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    @</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Override</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Date</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> convert</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Object</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> inputOb</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">MetaField</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">inputOb </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">==</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#91B859;--shiki-dark:#C3E88D">ISO8601</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">"</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">equals</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getDateFormat</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">()))</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">            OffsetDateTime</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> offsetDateTime </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> OffsetDateTime</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">parse</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">((</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> inputOb</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> DateTimeFormatter</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">ISO_OFFSET_DATE_TIME</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> Date</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">from</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">offsetDateTime</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">toInstant</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> DateUtil</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">parse</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">((</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">String</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> inputOb</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">getDateFormat</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">());</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// double类型转为金额格式</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> class</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> DoubleToBigDecimalConvertHandle</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> implements</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> ValueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    @</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Override</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> BigDecimal</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> convert</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Object</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> inputOb</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">MetaField</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        if</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">inputOb </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">==</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">            return</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> null;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">        }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">        Double</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> inputObTemp </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> (</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">Double</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> inputOb</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> BigDecimal</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">valueOf</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">inputObTemp</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">).</span><span style="color:#6182B8;--shiki-dark:#82AAFF">setScale</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#F76D47;--shiki-dark:#F78C6C">2</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 基础实现</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> class</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> BaseConvertHandle</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> implements</span><span style="color:#E2931D;--shiki-dark:#FFCB6B"> ValueConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    @</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Override</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">    public</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> Object</span><span style="color:#6182B8;--shiki-dark:#82AAFF"> convert</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Object</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> inputOb</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> MetaObject</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">MetaField</span><span style="color:#90A4AE;font-style:italic;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic"> metaField</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> {</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic">        return</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> inputOb</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">    }</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">}</span></span></code></pre>
<h4 id="2224-使用方式">2.2.2.4 使用方式</h4>
<pre class="shiki shiki-themes material-theme-lighter material-theme-darker" style="background-color:#FAFAFA;--shiki-dark-bg:#212121;color:#90A4AE;--shiki-dark:#EEFFFF" tabindex="0"><code><span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 注解的使用 - 将ES中的double格式数据转为Bean中的金额格式</span></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">EsValueMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#E2931D;--shiki-dark:#FFCB6B">convertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF"> =</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> DoubleToBigDecimalConvertHandle</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">)</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> BigDecimal</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> discountAmount</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#39ADB5;--shiki-dark:#89DDFF">@</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">Autowired</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">  </span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">private</span><span style="color:#9C3EDA;--shiki-dark:#C792EA"> AutoMapping</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> autoMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">;</span></span>
<span class="line"><span style="color:#90A4AE;font-style:italic;--shiki-dark:#545454;--shiki-dark-font-style:italic">// 也是通过一行代码即可完成对查询结果的转化</span></span>
<span class="line"><span style="color:#9C3EDA;--shiki-dark:#C792EA">List</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">&#x3C;</span><span style="color:#9C3EDA;--shiki-dark:#C792EA">PRCommonInfoDTO</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">></span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> queryResults </span><span style="color:#39ADB5;--shiki-dark:#89DDFF">=</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> autoMapping</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#6182B8;--shiki-dark:#82AAFF">mapToBean</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">(</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">queryResults</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">,</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF"> PRCommonInfoDTO</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">.</span><span style="color:#90A4AE;--shiki-dark:#EEFFFF">class</span><span style="color:#39ADB5;--shiki-dark:#89DDFF">);</span></span></code></pre>
<p>至此，上述内容对ES查询改造方案进行了完整详细的陈述，其中包括了对同步组件使用的说明，代码改造过程中遇到的问题以及对应的解决方案。从需求的提出、到方案的论证以及实际落地过程中，通过不过解决遇到的问题，让我在大数据量查询方案实践能力得到提升。目前该套方案已经在UAT环境中部署运行，对于文章中感兴趣或有问题及不足的地方可以联系本人进行讨论和订正。</p>
<h1 id="三附件">三、附件</h1>
<h2 id="目前主流es客户端的优缺点比对">目前主流ES客户端的优缺点比对</h2>
<table>
<thead>
<tr>
<th>客户端类型</th>
<th>适配版本</th>
<th>是否官方</th>
<th>特点简述</th>
</tr>
</thead>
<tbody>
<tr>
<td>Rest High Level Client</td>
<td>ES 6.x ~ 7.x</td>
<td>✅ 是</td>
<td>语法清晰，逐步废弃</td>
</tr>
<tr>
<td>Java API Client</td>
<td>ES 7.15+ / 8.x</td>
<td>✅ 是</td>
<td>新一代，类型安全，推荐新项目使用</td>
</tr>
<tr>
<td>Spring Data Elasticsearch</td>
<td>多版本匹配</td>
<td>✅ 是</td>
<td>Spring 生态集成，声明式开发，适合 CRUD 场景</td>
</tr>
<tr>
<td>Jest Client</td>
<td>ES 6.x</td>
<td>❌ 否</td>
<td>简单易用，但已不维护</td>
</tr>
<tr>
<td>Low Level REST Client</td>
<td>所有版本</td>
<td>✅ 是</td>
<td>低级别封装，自由度高，复杂度也高</td>
</tr>
<tr>
<td>选择<code>Rest High Level Client</code>的理由是：目前生产ES服务的版本为6.4.2，且当前的查询逻辑较为复杂；</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="adapter的源码项目结构说明">adapter的源码项目结构说明</h2>
<p>将对本地同步涉及到几个模块进行说明，方便在看到的时候有方向</p>
<pre><code>- canal-canal-1.1.8
  - client-adapter
    - launcher/main # 启动入口、生命周期控制
      - java 
        - loader
          - AdapterProcessor # 适配处理器, 具体的处理类
          - CanalAdapterLoader#init() # 代码查看的入口 **
      - resources
        - application.yml
    - common # 公共类
    - es6x # es请求执行模块
    - es7x 
    - es8x # 不同的版本
    - hbase # 同步到hbase时调用
    - ...
</code></pre>
<p>通过<code>CanalAdapterLoader#init()</code>入口，一步步点进入看就好了，代码逻辑比较清晰简单。源码down下来之后可以本地运行调试下，会熟悉的更快(配置文件修改resoureces下的application.yml即可，配置的方式参数上文中的配置描述)。</p> <hr> <a href=https://blog-orcin-five-66.vercel.app>Han's 世界</a> <p>记录自己的当下</p>  <p>作者Han</p> <p>2025 June 15th发布</p>]]></content:encoded>
            <enclosure url="https://blog-orcin-five-66.vercel.app/og?title=ES查询改造方案" length="0" type="image//og"/>
        </item>
        <item>
            <title><![CDATA[糟糕的爱情经历]]></title>
            <link>https://blog-orcin-five-66.vercel.app/blog/mybadlove</link>
            <guid>https://blog-orcin-five-66.vercel.app/blog/mybadlove</guid>
            <pubDate>Mon, 09 Jun 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[糟糕的爱情经历，足以毁灭掉一个人对爱的向往]]></description>
            <content:encoded><![CDATA[<p>糟糕的爱情经历，足以毁灭掉一个人对爱的向往</p> <hr> <p>  爱情是一个大多数人想要获得到的亲密关系之一，我的恋爱经历不少但都很短暂或者并没有很深入的体验。
从审视的角度来看，我确实是一个花心、不专一的人。小学、初中、高中，在我的世界观中并不懂什么叫责任感，也不知道什么是克制，什么是爱。学生时期的我，始终处于男生的性冲动驱使中，不断的寻找所谓的女友。大学后虽开始逐渐明白，但现实的因素给了一击。而毕业后的爱情经历，让我知道只有从一而终的人才值得拥有爱情，而我需要用一生去为我的过错买单<br>
</p>
<h1 id="小学">小学</h1>
<p>  我依稀记得小学六年级是我的性启蒙时刻，那会通过同学口中绘述中的"人体艺术"第一次接触到性知识，当时并不知道太多，只知道看这些内容会舒服。而这也让我开始希望在现实世界中进行真实的接触--寻找"女友"。我的第一次求偶对象是我的小学同学，我们初中也在同一个学校，我和她之间并没有实质的男女朋友关系，更多的像是两个可以在线下看到的网友。我和她之间的联系集中在六年级到初一，虽然我们都在一个学校上学，但我们之间未曾有过肢体接触，文字和网络构建了我们之间的全部。和她最让人印象深刻的是，我们在初一有次开玩笑，约定10年之后也就是在大学毕业如果两个人还能互相喜欢那我们县城的体育场相见。“想想也是很幼稚的一个的约定”。事情的结局是，在我大一的时候她选择了高复，我们有些偶尔的联系。大二的时候她进入大学，当她委婉的问起是否还记得我们之间有个约定的时候，当时的我选择了装傻充愣，我们之间终究也是维持在朋友的关系。“那会的我完全沉浸在大学的自由中，满脑子只想体验新鲜事物”。疫情那会我们因为线上狼人杀，又重新联络上，虽约定有机会吃个饭。但最后的最后，她的微信因为前女友的要求删掉了，她也始终只是在我的记忆中出现过。“网络社交是一个神奇的工具，可以让超过10年没有再见过面的两人旧人依然能保持联系”<br>
</p>
<h1 id="初中">初中</h1>
<p>  初三，一个青春萌动的年纪。那会是山寨机横行的时候，班里的人开始偷偷用起属于自己的手机。不出意外的我，用攒了好久的零花钱买了一个山寨机。(400？当时零散的钱拿去店里的时候，还记得老板那即无奈又好笑的表情。)当时手机上的QQ有人给你发消息的时候，图标是会一跳一跳的。就这样我和班上的一个女孩聊上了，她善良、可爱、天真，很爱笑。我们之间的恋爱，小心翼翼，毕竟学生时期的恋爱是不被允许的。那会手机也是不被允许拥有的，毕竟家长会觉得这个会影响学业，每天晚上躲在被窝里聊天的场景时有发生。(那会充电用的万能充，跑马灯晚上充电怕被发现还会用布盖住。有意思的回忆，现在想起来嘴角还会扬起)当时学校会让每个班级轮流对学校进行清洁，我会故意跟她一块，一次当我看周围没有人的时候我偷偷亲了她一下，她当场定住了，那是我第一次接吻，也是她的第一次。意外不期而至，我们之间的聊天被她妈妈发现，然后打电话给我妈(我用过我妈的电话给她打过电话)，我不知道具体的通话内容是什么。我记得，那天我爸一如既往的开着摩托车来接我下晚自习，他没有批评我，他只是问我有没有在谈恋爱，然后说人家家长打电话过来了,"你应该要知道在什么年纪做什么事情"，当时的我并没有真正领悟这句话。“我清楚的知道我们之间的聊天充满了青春期对性的幻想”。我们之间也在毕业之后，分道扬镳。  <br>
</p>
<h1 id="高中">高中</h1>
<p>  高中，给我的一次冲击就是课程的难度相较于初中有了极大的提升。第一次考试的时候，我竟然不及格，这让我很难以置信，毕竟初中的时候不及格是一个天大的事情了，彼时我不知道的是这将是我接下来的常态(╮(╯▽╰)╭)。整个高中阶段，我总共跟4个女生产生过故事，Y、X、Z、H。<br>

  Y是高一上半学期尝试追求的女生，未果。  <br>

  X是有次周末放假没回家，和大家一起在学校，那晚我们一起玩游戏的时候，我们暧昧上了，当晚我们做了比较亲密的事情，但是没有越界，也没有了然后。  <br>

  Z是我当时的前桌，我们有段时间在QQ上聊的很火热，我对她产生了好感，同时我也以为她也是，但她突然戛然而止-没有回复你的消息，当时的我认为这是拒绝的信号，我也没有继续释放我的心意。当时的我不知道的是，这个人在10多年后的今天依然影响着我--她成了现在的我的前女友，滑稽的是按计划她现在是我的未婚妻。  <br>

  H，是我人生目前为止，觉得唯一亏欠的人。如果可以穿越时空回到未来，我想我会回到那个时候跟当时的我说“你不应该去勾搭她，你配不上她”。文静、温柔、心善、美丽... 我想一切关于好的形容词放在她的身上都不足为过。她出现在Z没有回应我之后，被我默默作为无处宣泄的出口。她被我满嘴花言巧语所欺骗，她占据了我的高中的大部分时光，而我未曾有过给她对等的爱的付出。我们之间从未有过争吵，从未，当时的我觉得这很无聊(多年后我才意识到，她是我再也遇不到的女孩)。她给我的是真诚和爱，而我反馈却是无尽的龌龊。在上大学后的一段时间，我跟她提出了分手。现在回想起来跟她的时光，我感到的都是亏欠，对她我有的也是无尽的亏欠，“对不起”。她是我真正意义上的初恋，虽然我们在一起很久，但我没有带她去逛过街，没有带她去吃过饭，一次都没有，对她我不可饶恕。<br>
</p>
<h1 id="大学">大学</h1>
<p>  大学的时光，是自由，热烈的探索。第一次走出县城，开始探索这个世界，我像是一只飞出笼子的鸟，接触不同的人，去体验不同的事情。大二的时候，跟同学在校外办立一个桌游俱乐部，在基地里面每天晚上跟来自大学城不同的人玩耍，一段值得回忆的快乐的时光。大学里面我更多的体验各类我未曾接触的事物，当时间来到大三，有个女孩引起我的注意。她的侧脸完全是我的理想型，那会我在做家教，周一到周五每天下午6-9点。每天在公交车站能看到她，她的美丽也让我印象深刻，但我也只是欣赏的想法。本以为日子会这样一天一天的过下去，我会在大三结束的时候，找一份实习的工作，然后工作挣钱。但在大三结束的前一个月，那天要上一节早课，我起晚了匆匆忙忙跑去课堂，在楼下等电梯的时候，脑子里刚好在想这个女孩。不知道是不是上天的故意安排，当电梯开门的瞬间，一个女孩擦肩而过。是她，一个熟悉的侧影，我的心率瞬间飙升。那天的课我完全没有在意，座位上的我内心久久不能平静，那是我的心动时刻。在之后的几天，她一直在我的脑海里盘旋，一天晚上室友叫我去夜宵摊吃点，我嫌弃太晚拒绝了。而他说，去可能能碰到那个女孩，就这样我两打赌似的出发去了。是的，我又遇见她了，在小吃街的一个转身，不知道这是不是叫做缘分。当晚室友帮我打听到了她的电话，加上微信后没多久我们就确定了关系。我们几乎每天逛大学城，我们去吃各种好吃的小吃，那段时间是一段开心无忧的时光。她彼时还是大一，我们在一起没多久我就找到了杭州的实习工作，她还需要在温州上学。刚来杭州的时候，几乎是三点一线，上班、吃饭、睡觉，唯一开心的是我们每天晚上会视频，她会不停的分享她的一天，这种感觉真好。有天下班，她打电话给我说她在我的身后，我肯定不相信呀。我的天，当我转头的瞬间我的眼泪就出来了，她真的在。当时杭州就两条地铁，我在未科，温州过来需要高铁、地铁、公交，她才大一，一个人拎了一个包，手里就一个我公司的名字，就过来了(我大一的时候高铁都没做，去温州上学跟乡巴佬进城一样)。而她过来的原因只是因为我视频里面跟她说我想她了，所以她就过来了。而我，在她脚被烫伤的时候，却没有回去陪在她旁边，我以为她说不用是真的不用，彼时的我不知道有时候需要直接做。在确定关系的几个星期后，我们就一直异地，在我来杭州的几个月后我们之间也就结束了。  <br>

  这次的恋爱算是我一次真正的处于恋爱之中，因为上一段没有好好的对一个女生，这一段我尽当时自己的可能去做。当然我也感受到了对方对我的付出和爱，虽然最后并不是happy ending，但我们之间也并没有太多的矛盾冲突，只是缘分结束了而已。在分手后的一周，我回去找了她一趟希望寻求复合，我们在咖啡店里长聊了之后，虽然很难受但我知道我应该保持距离了。多年后的今天，我拨通了那个多年未拨的电话，电话那端从起初的惊讶到平静，我们聊了这几年的经历，她还是一样的会分享着自己的各种经历，不同的是这些经历改变了她。当她问起我为什么突然给她打电话，还是隔了这么久之后，我不知道为什么，“就是想打一下，并没有任何的目的”，是的，就只是如此，也仅仅是如此。  <br>
</p>
<h1 id="工作后">工作后</h1>
<p>  工作之后，我一直很难去展开一段恋爱，我不知道我的哪些既有行为会让对方觉得不能接受，我不排斥修改自己的行为，我害怕当自己陷入亲密关系的时候，对方会因为你的一些行为，直接选择放弃，而不是选择沟通解决。而且毕业以后，看到的，听到的人和事都让我觉得爱情这个事情并不纯粹。<code>我希望自己的爱情可以尽可能的纯粹。“面包和爱情”，我会认为建立在一定面包基础上，才能获得我理想中的爱情，因为面包确实会消耗爱情 -- 喜欢一个人，由心的喜欢这个人本身，无其它的任何外部事物。爱情可以让两个人在面对人生坎坷中并肩前行，面包可以将这些坎坷填平，让两人注意力专注于对方而不被影响。</code><br>

  几年后，一段朋友介绍的对象，让我平静内心波起一层涟漪，温和而短暂。认识、确定关系、结束短短一周，只是一段经历而已。不过让我学习到的经验是，说话不能太直男，需要懂得夸人，是一个有用的经验适用于各种场景。坦率并不会被认为是一种好的品质，没有人喜欢被人直接说出缺点，尽管你并没有恶意并且你们是亲密的人。<br>

  时间又过了几年，这篇文章的主角出现了，一段足以击垮我对爱情期待的经历，我不知道我何时能整理好自己的内心。以上的经历，我更多的是将其归为爱情中美好的一面，而这段让我认识到了爱情中的欺骗、虚伪、恶心，那些让我只在网络看到的事情，不曾想发生在我自己的身上。她就是上文有提到过我的高中同学Z。</p>
<h2 id="重见">重见</h2>
<p>  我们高中毕业之后，一帮同学也会常聚在一起玩耍。毕业之后她去了上海，而我在杭州，我们在节假日的时候回老家还会偶尔碰面。期间也有听闻她恋爱的消息，她在上海待了几年之后来杭州，当时她的计划是准备出国去留一年学提升下学历。当她确定出国的前夕，我约她出来吃饭，那是第一次跟女孩子以朋友的关系单独吃饭。而我为什么要约她出来？我无法说清，是对曾经的好感未完全的释怀？是的，她确实一直在我的内心中，这听起来是一个很违背道德感的事情，毕竟我在她之后有谈过对象，但她确实一直在我的心理藏着。在大二有段时间，我们因为狼人杀聊的火热，发小也看出来我对她的心意怂恿我去表白，但后来也因为她没有回复我的消息让我再次的收起了自己的心意。(后来交往的时候知道，我只是她聊天的其中一个人而已，而她也只是帮我当作普通的同学。尽管，那会我们会偶尔语音，在我看来是会超越普通同学的行为。)<br>

  我们约在一家韩料店，聊着她的出国的规划、这几年的工作经历以及日常，还算不错的过程。饭后我们去西湖散步，记不清当时聊的具体内容了，只是有一茬没一茬的边走边聊。那天的温度刚好，风也刚好，我也感觉我们越走越近(后来当我问起她的时候，她说她并没有觉得两个人走的很近--当我客观的认为我们之间的氛围超过了普通的同学，但她并觉得没有。多数人会认为上头的人会更加的自作多情一些，但我没有编造，我在陈述客观事实)。<br>

  那天过后，接下来的几天我们会有在微信上有一句没一句的聊着天，然后她约我去看脱口秀，我欣然接受。脱口秀看的很开心，看完后我们去吃火锅，那个火锅很辣，当时也是晚上8，9点了。而我对她的心意，也是在这次火锅中说出，我不知道为什么会在此刻说出，可能是自己以为自己准备好了，有足够的勇气了吧。她没有给我一个明确的回复，拒绝和同意都没有。饭后，我们坐在西湖边聊了很久，过去的各个时刻，沉寂在内心的各种，直到深夜。聊完后的我们依然意犹未尽，我提议去宝石山去看日出，所以我们去了。就这样我们在宝石山上坐了几个小时，也看到日出，很美。那天我跟她描述着我期待的爱情是什么样，而她是我唯一愿意再次勇敢一次的女孩，也会是最后一次。那天她说“她很难再去相信一个人，纯粹的爱情她并不相信，我太天真”。从她的言语里我感受到了是被受伤的心，而我说“我虽然看到过爱情的糟糕，但是我依然相信爱情的美好，我希望与你一起发生。面包和爱情我觉得都很重要，我会达到基础的面包，与你我希望是爱情”。“对你我是有好感，但还没有到喜欢，出国这一年我不准备谈恋爱，如果我回来你还是如此，是有机会的”，这是日出结束后她给我的回复。我很开心，是的我真的很开心。</p>
<h2 id="异国">异国</h2>
<p>  那之后我们几乎天天在微信上聊天，刚出国后的那段时间，我们也经常视频。迅速升温的感情，让我觉得异常的开心，每天早上睡醒的第一见时间就是看看有没有微信留言。我建立了一个在线的留言板页面，像一个时间囊，我们两个会在上面偶尔留言，我也会反复观看历史留言，我希望可以在一年之后回过头来看会很有意思，页面上的倒计时标记着我们再次见面的时间。而再次升温的氛围，再次戛然而止，她对我说我们之间目前的状态跟情侣没有区别，但这并不对，我们并不是而且她这一年并没有打算谈恋爱，她需要专注学业，而我会给她压力。我知道我需要再次收回我的心意，我克制着我的爱意，尽量的不去打扰她，那之后我没有再找她聊天，我只是默默关注她的动态，当忍不住想跟她说话的时候我会在留言板上面写下自己的心意，她也会偶尔在上面进行留言。我也只是在继续我的生活，她希望我更健壮，会做饭，所以这一年我报了一个健身房，跟同事一起一周4练，周末去骑骑自行车，也开始自己学着做饭。当然这一年，我也为面包努力，当我发现我的每日平均工时超过10个小时也涨薪无望的时候，我寻找副业机会，那段几个月的时间我几乎每天只睡几个小时，幸运的是我也得到了回报，在工资之外解决了装修款的资金问题。<br>

  这段时间比较难的是你需要抵抗各类言语，旁边亲近的人会跟你说，“如果一个女生对你这样的回应，那她就是不喜欢你，放弃吧。”，“要么答应，要么拒绝，不会这样既不答应，又不拒绝的情况的”，“她只是拿你做备胎而已”等等诸如此类的言语，但是当时的我坚信她不是这样的，她只是确实在这个阶段不想谈，她也不是会养鱼的女孩。(后来我看到她的聊天记录，我在她的描述中是“舔狗”，言听计从的感觉让她很爽，之前从未感受过 -- 然后她在我面前的描述自己是感情受伤，害怕相信人，希望对方主动)</p>
<h2 id="我愿意">我愿意</h2>
<p>  一年很快过去，回国后她并没有马上找工作，而在家完成剩余的论文等，然后在找工作。我们又重新的开始聊天，恢复往常一样的每天聊天。我陪她去考试，一起去动物园，一起去吃好吃的，我们聊天也愈发的暧昧，但突出也随之而来。在春节前夕的一晚，她跟她爹出去练车回来之后发了一段小红书的截图和我说“我目前的行为有点消耗她的精神气，有点挡她的桃花”，然后她问我“如果有一个相亲对象，家里人希望我去见面，然后你会咋想”，“从朋友的角度，我会让你选择去见面，因为这没有啥问题。如果作为追求你的角度，我会选择放弃你，因为我不太喜欢被选择的感觉”。我会认为既然你会选择去相亲说明你对我某些方面是不满意的，那你就不是真的喜欢我，所以我会收回对你的爱意。对她来说，她希望我可以要变得上进，有主见比她强。-- 我希望的是可以做女生的后盾，每个人都是自由的，我希望我爱的人也是如此，她可以自由的做自己，而我会一直站在她身后，只要她需要我的时候我都会在并予以帮助，这不是谁比谁强，而是我爱她，我愿意为她创造她自由所需的一切并将各种阻碍清除。她跟我说对她来说，如果一个人同时被两个人追，先接触一个人当不适合的时候，再去跟另一个人接触没有问题。对我来说，当做出与一个人接触的决定的时候，那就说明对另一个人是不喜欢的，所以另一个离开是没有问题。而我作为其中的一个人，我会选择离开，但她会觉得的你这样离开是不够爱，不够坚持。我很难理解也接受不了这种恋爱观，那天晚上的聊天也不欢而散，她也将我删除拉黑。她跟我说她慕强，而我在她眼里更像一个弟弟。对我来说，我不理解我的尊重在她的眼里会是能力不足，而这种自高一等的心态，也是我最终选择方式的原因之一。<br>

  本以为我们之间就此结束内心难受痛苦的时候，她在除夕那天加回我的微信，并约我出来再次见面。我不理解为什么这么做，但看到消息的我确实很开心，那天我早早的去接她，然后我们在县城的盘山公路上从阳光明媚聊到了日落晚霞，她也将这次的冲突定位为两边的误解。她希望我的回答是“你可以因为我不去相亲”，而我认为“当你能说出这些话的时候，说明你对我并不满意。我希望你喜欢我可以因为我这个人本身而无外乎与其它”(事实是其实我们的恋爱观或者三观并不一致，事后她也同样认为她当时对选择看法的言语并没有问题)。在这之后我们的感情再次升温，在年后的情人节我也向她再次告白，我们也正式的在一起了。</p>
<h2 id="爱情里的酸甜苦辣">爱情里的酸甜苦辣</h2>
<p>  在一起之后，我沉浸在表白成功的喜悦中，但我也忽略了恋爱中需要的平等与相互尊重。年后那段时间，她准备着各类春招面试，因为面试是在杭州，所以会在需要面试的时候，暂住我这里。这也是我噩梦的开始，她会因为我的各种行为言语不满，她会觉得我做的有问题，而我会去尽可能完整的去解释我为什么会这么去做，我的逻辑是什么，尽管我认为自己确实符合逻辑没有做错，但是在她看来就是不对。而我在解释说明完之后，也只能是一味的道歉，彼时的我以为女生都是这样，会有一些小脾气，会需要哄。所以，我会为每件她不舒服开心的事情去解释说明，道歉保证，这样周而复始的哄她直到她开心满意为止。而这样的行为持续了好几个月，那段时间一周7天我几乎需要哄3，4天，每天晚上几乎都是12点多，1点多睡觉，更甚至到3，4点，然后第二天接着上班。那时我从刚开始的身体累，到后面的害怕，我开始害怕自己说的话，做的行为在她看来是不对的，但彼时的我还会认为这些都是正常的，我跟自己说毕竟两个人刚开始总会有各种观念不合的情况。现在回想起来也是替自己不值，她会时常跟我强调她的前男友虽然有点渣但是能力很强，她是慕强的。她会给我发她的前前男友照片给我然后来反驳我，说他长得帅。以及追求她的男生都没有差的，等等种种在我理解如果一个人喜欢另一个人根本不会说出的一些话，但她会真真切切的跟你说出来。她会因为在景德镇逛的时候我一句一个几百的马克杯有点贵可以在看看的时候，直接甩人就走即使是当时众多同学的面。她甚至会在我外婆去世守灵的晚上跟我说这是一个陋习，尽管我说这是风俗你可以不做但我需要做的时候，还是会朝我发脾气要跟我分手并将我删除拉黑。我不理解她的行为，或者是我不敢真正去面对她的这些行为背后的逻辑，那就是她其实不够喜欢你，她只是选择跟你在一起了，你只是她在当时的一个较为好的选择而已。求同存异，有不同意见的时候，我希望两个人是可以好好的去沟通表达自己内心的想法，然后去商量如何去解决问题。</p>
<p>  每个人都会有自己的过去，对于我来说我不关心她的过去，我只需要她跟我在一起之后，我们两个好好的经营自己的世界。而她的这些行为让我开始对她是否真的喜欢我产生了怀疑，而我开始寻找这个问题的答案。</p>
<p>  答案给我的第一个冲击就是，在一段我以为度过磨合期的时候，她跟我说她其实在上海那段她经常提的渣前男友之后，其实在杭州不止谈过一段，还有一个但是因为当时觉得自己被人家骗炮了所以一直很难以启齿。这让我很崩溃，因为她之前一直跟我描述的是她被上海男友渣了之后一直不相信男生了，她对我的表现也一直是自己是受伤的人，所以希望对方主动。那天晚上知道事情的我，很难接受，然后事情发展并不是她来安抚我的心情，而是觉得自己这么坦诚了为啥我不能接受她，然后她就开始生气，然后要分手要自己搬出去住，而事情的结局还是她一个电话我就屁颠屁颠的跑过去然后这件事情就结束了。(事后我才知道，那个男生并没有骗她，而是她自己主动加那个男生尽管她的同学已经劝她不要深入了解那个男生是一个渣男，但人家家里有小实力。这也让我见识到，同样的一个女生她可以对你如此被动，但主动起来是多么的主动。在我的面前，她描述的自己总是弱势的一方--<code>女人的眼睛是会骗人的</code>)<br>

  然而更多的真相总是痛苦的，是极致的痛苦。当知道事物的另一面之后，坦率的来说我的世界观是崩塌的，我从未想过一个人可以如此之坏，而且是发生在自己身上的坏。尽管在上次事件之后，我们两个人会足够的真诚相信对方的时候，我还是能感受到她因为跟我一起的委屈感而跟我因为一些话语或者小事生气争吵，我很难理解这种委屈感为何而来。我在一个晚上偷偷备份了她的手机信息，并从中提取出来了微信聊天记录。看到记录的那刹那，我在工位上手一直在不自主的抖动，眼泪无法控制，呕吐感随之而来。尽管已经过去了将近一年，但每想到这些内容我的心还是会抽搐。<br>
</p>
<ul>
<li>我在追求她那会的时候，她对我说的是“有好感，没到喜欢，希望对方可以多主动”，但她跟别人说的是，她明确已经拒绝我了，我像一个舔狗，之前都是我这么对人家，原来这种感觉这么爽。</li>
<li>她的上海前任是她当时的上司，大她有快10岁了。而她也从来没有忘记过他的前任，她不止在我面前提她的这位男友，她还会背地去拿我和他进行比较，而她也从未忘记过这位男友。</li>
<li>嘲讽我的爸妈没有收入，并觉得我们家条件不好，如果不是有拆迁现在日子都不好过，觉得跟我在一起是自己降低标准的选择，她觉得我的收入和能力也一般，自己比我强很多(那会她还正在找工作)。-- 事实是：1.我的能力确实不怎么样，一年单纯工资收入只有20万的收入，我也只是一个随遇而安的人，我希望更多的是体验生活而不是被既定绑架。2. 我家为我在杭州买了一套房，虽然有贷款但是首付出了150W多，还贷到现在不到100W的贷款总额，每月的还贷额度不会影响目前的生活，房子的装修是我当时通过副业挣得的将近25W。3. 我爸妈本身在当地的县城里(在浙江里面)有自己两间落地房和一套大面积商品房，拆迁是我爷爷奶奶村里的房子，因为位置比较好，虽然说是农村但和县城一街之隔，和县政府隔河相望。爷爷奶奶的四合院以及现在的落地房，也都是我爸妈当年靠自己打工做生意攒起来的家业。后来生意失败后，虽一直没有工作，但是在从事炒股，也是够养活一家人，并给了我们超越基准线的生活水平。4.我爸妈为在我姐出嫁的时候为其几乎全款购买了一套房作为嫁妆，房总价比我的还贵，没有收取彩礼连酒席都是出钱帮忙(不要在意钱，你只需要关注对方是否是你真的在意的人 -- 我的父亲是我认为一个真正践行男女平等的人，我很感谢他为我树立的观念)。 反观她：1. 她觉得自己在上海一年可以有3，4十万的收入是自己的能力，但是更多的是因为所在的是一个小额网络借贷公司，背靠兴业银行是平台和时代给的红利，她从事的也是电催的工作内容并没有太多的能力展示内容。她之后找到的银行工作是柜台，一个月也仅够自己的开销。2. 她会觉得自己出过国留过学，但我认为这种只是有钱不是弱智就能出去的水硕而已。我们只是任务不同而已，她可以毕业6年身为分文，我需要为爱情准备面包。3. 她的家庭也只是一般的小康水平而已，有一套县城里面的落地房通过继承而来，父亲是工厂的工薪阶层，妈妈是餐厅工作。在我看来我很理解她为什么会有这种想法，她会觉得自己跟很多有能力的人共事或者相处过，自己就是那类人，但希望自己成为和自己就是是两回事情。我的哥姐，不乏高学历和高收入的人，但我知道自己的能力在哪。两家都是小康家庭，为啥会有莫名的优越感出来，很难理解。</li>
<li>在她上海回杭州的阶段，通过自己的姑姑介绍去认了一个退休了的浙江省官员做自己的干爹。而这个所谓的干爹，也只是微信上的相认，并不是正常的那种自己父亲认识的好朋友，有正规仪式的过程。她的姑姑之所以认识这个人，也只是通过自己的一个相亲对象作为跳板认识，他的姑姑是上年纪的人岁数，这位干爹也是上岁数了。真的很难想象，会有这种情况，而她通过这个干爹希望达成的目的是希望通过这个关系在杭州帮自己找份工作。更难想象的是，她会陪这位干爹逛街，看电影，在宾馆房间中共处。(她跟我说没有发生什么，这位干爹只是在房间里休息。我问她那你为什么会跟进去，她也只是支支吾吾的跟我说当时自己没想这么多 -- 这个事情的真相这个世界上也不会有第三个人知道)。聊天记录来看她们还有过别的宾馆的记录，但她都否认说另外一个只是在楼下喝茶，而他们之间的聊天内容在我看来也客观的超过正常关系之间的沟通。而所有的这些都是她的过去，她再跟我在一起之后，又跟她这位干爹出去吃过几次饭，当我问她跟谁出去吃饭的时候，她都只是说不方便说，我也选择尊重她而不追问。这位干爹也一直几乎每天跟她发消息，而我从没有从她的口中听到她说过。上面所有的一切都是我根据自己看到梳理到的，尽管我拿着聊天记录问她的时候，她还会前后文对调，或者记忆模糊的说法模糊其词。</li>
<li>自己想要买房，觉得婚前女生要有自己的房子，我觉得挺好，然后说那刚好以后上班可以在你买的公寓中住，周末来我这边住。然后她跟别的高中同学却说我在逼她买房子，而上海的前任顶多也只是让她买车。？？？？？一个人怎么可以做到这么坏</li>
<li>自己希望买车，当我说想要买车的话，其它方面的开销就需要省一点因为目前的收入是固定。然而，她会跟我说，觉得自己跟我在一起委屈了，之前自己一个人的时候过的很舒服想买什么就买什么，有多少就花多少。我？？？自己想买车，收入又只有这一点，其它不省，哪来的钱？？哪有既要又要，然后跟我发脾气，要跟我分手，我还得哄...</li>
<li>跟我说自己是一个需要仪式感的人，希望我在每个节日都能送她礼物，礼物无论贵重不重要，重要的是心意。<br>

· 我们刚在一起时我送她了一个AppleWatch<br>

· 生日的时候除了鲜花吃饭我送她了一瓶1千多的香水 -- 她当着我的面说很开心很喜欢，背地里却跟同学吐槽我送的这么廉价<br>

· 520的时候送她一个金项链<br>

· 情人节的时候给她买了金戒指，却跟我说算便宜我了，这么就打发了。但是戒指也要4K多，几乎是她一个月拿到手工资的全部了。<br>

而她只在我生日的时候给我买礼物还是我自己的挑的800的鞋子，她去亲自给我买的一个蛋糕就感觉自己付出很多，哦对了那次的吃饭是她请客付钱因为我生日。然后当天，因为她离蛋糕比较近让她拿下，她就直接开始发脾气。想想也是可笑，那天晚上的蛋糕我是自己一个人吃的，所有物品价值的钱也转回给她，当然这也算是她唯一一次给我买礼物。</li>
</ul>
<p>等等等，各种让我难以接受的事情。当看到这些的当天，崩溃的我跟她提出了分手，但我没有跟她说明我看了她的聊天记录。不曾想，第二天她跟高中同学出去诉苦，我请假在家缓冲了一天。回到家后她竟然跟我说，那些高中同学也劝她分手，觉得我是断崖式分手，但是她不忍心看我难受？？现在回想来看当时的我是真的“贱”，怎么自己还委屈上了，她从头至尾没有关心我的情绪，只是一味的表达她自己因为我的提分手很难过，过去的事情为什么要在意。而我在意的是我寻找的答案，我不敢面对的竟然是真的。然而，在接受过去和失去爱情中，我再次选择了爱情。<code>我跟她说我在意的不是过去，但是我希望你喜欢的是我这个人本身，也需要对我坦诚，这些事虽然我可以接受但是需要时间的安抚，我会在每次我想起来的时候感受难受，我希望你可以照顾下我的情绪，随着时间的推移这些事情会被慢慢淡化掉</code>。<br>

  这件事情之后，我以为我们之间不会有再大的坎坷了，而我在意的悬而未决的干爹的问题，她也答应我会跟她爹说让家长去解决这个事情。我们也开始进行见家长，聊婚事的流程，这也是压倒我们之间关系的最后一根稻草。在两边家长见完的那天，她们家是要收彩礼的，然后单订婚起码要10桌，因为亲戚比较多，五金这些也需要。我们这边彩礼的入门价格是18.8W，那天晚上我们之间商量说明整个结婚过程中的开销，<code>彩礼：18.8w、订婚酒席等：5W、五金：10W、结婚酒席：30W、车子：25W</code>(车子我现在有一辆高尔夫但是是家里的虽然是给我再开，商量过程中她希望有辆自己的车)，然后我跟她说这么一算整个过程花的有点多而且都是这一年的事情，我手里现在也没多少，能不能彩礼钱收走之后你爸妈也是给你的，我们拿来办婚礼缓解下我爹的压力。房子也已经买好了没办法，车子你想要的话我今年手里攒一攒，如果到时候实在不够再问我爹要点然后婚前也写你名字。这样既让你们家名面上收了彩礼，也能说这个车子是你们家的嫁妆，面子也能盖的过去，里子也能周转的冗余一点。最后我也跟她说，这是我们之间商量的方案，如果他爸妈问起这方面的事情，有别的想法的你就答应过来，然后我们再商量，如果你爸妈没有想法的话我们就按这个方案走。令我没有想到的是，那晚本以为两边都认同的方案，在第二天却变了卦。她明确需要彩礼，我很不解我问她理由是什么，她的回答是“订婚了之后，就没有收钱这么一说了，之前理解错了。” “我需要保障”。当我问她那如果要彩礼的话，整个过程需要花这么多钱需要怎么办，她给我的回答是“那我们可以先不办婚礼，等攒够钱了过几年在结婚”。那我们可以先领结婚证吗？她回答到“那不行，需要婚礼办了之后才行”。整个过程中，她没有说一句那我们可以省点钱办，或者她们家也可以出出力。尽管我跟她解释说明我们的遇到的问题是什么，我们要尝试一起去解决。她只是关心的是我不想给她彩礼，我没有把她当作自己人。她开始将自己感受的委屈去跟周围的同学进行诉说，自己想要买车诉说成车子买来还是给我开，其次把在商量的时候明明说自己看我姐的婚礼办的很好自己也想要说成婚礼不要也行，可笑的是当同学听到我不想给她彩礼是因为想给自己的爹减轻压力这一片面的话词之后，都会认为我是自私的，不尊重女方。而这些让她觉得更加委屈，因为她觉得就算这样还想要跟我在一起？？？(就是在同学的面前展示自己很委屈但是还想跟我在一起，然后在我面前表现的是“你看大家都劝我不要在一起，我还要跟你一块，你还不知足”？)这是让我感觉到及其恶心难以接受，却又无法反驳的。尽管我尝试去她家，当面跟他爸妈解释清楚这个事情，并不是不给的意思之后，也还是未能挽回整个局面。(后来分手后，她骂我的一部分也是如此，她以为她给了我机会让我重新相处的机会，但我确没有好好把握)。<code>她上海的男友当时让她出装修钱，她也并没有觉得有什么不对，在她的世界里标准差是需要用钱来填平的。</code><br>

  于我真正做出分手的原因是，尽管我们经历了这么多的摩擦之后，我们依然没有建立一套有效沟通方式以及一起解决问题的方式。她依然会因为我的一句话我大发脾气，依然会跟你缠到凌晨几点不让你挂电话，依然在打了好几个小时电话我爸妈叫我有事情我挂断的时候，会说“没有我的命令你不能挂”。我们之间聊的内容永远没在同一个维度，我希望的是如何解决问题，而她会一直觉得我的态度不行我的话术不对，我没有听从她的。她在我因为回忆心情难受的时候，第一反应不是去安慰我的情绪，而是质疑我为什么要去怀疑她，她从未为她的过错跟我说抱歉，从来都是通过沟通中我的话语抓我的瑕疵，然后转化为自己生气的点。每一次都是这样，原来明明是我生气的点，最后都要我倒过来去哄她，而她对外却一直说我在弄她生气。最后的时间，她发了一段长文跟我说她还爱我，但是需要一段时间去调整下自己的状态，然而过了一个星期之后，她却打电话来说自己看开了但是只是舍不得，真的是一个虚伪，另人恶心的女人。在之后的一个月，她再次给我发了一篇都是骂我的话，很难相信一个你曾今打开心扉将自己底层的秘密展示的人，会被那个人拿过来作为攻击自己的刀。<br>

  这段感情里面还有太多太多回忆起来令人可笑的事情了，然后这些所有的一切，在外人或者她自己本人看来都是我的错，她自己会觉得自己都降低标准来找我了，为什么我就不能顺着她。对于那些同学来说，他们视角里的我是一个起初热烈追求，追到后就不知道珍惜，只会在意女生过去又不想给彩礼的一个自私的人。但在这段感情里面我从未有过私心，在面包方面我能自己做的都自己去做到，从未贪图对方任何面包。我在意的是对方是喜欢我这个人本身，无外乎与其它。极致恶心的是：她在外塑造的形象是非常爱我，虽然我有各种不好，但还是想跟我在一起。真的是极致的虚伪。</p>
<h1 id="思辨">思辨</h1>
<p>我已经不知道在感情方式我是一个怎样的人，从经历来看我也算不是一个专一的人。这些不同感情经历，让我学会了不同的人生道理。我不知道我当前分手的决定是否正确，我为此也放弃了高中那帮至今已有10多年的朋友的交往。我不善也不喜欢将两个人的感情公之于熟悉的朋友圈子之中，在我看来大部分的人对感情只是吃瓜的态度，有时并不是他们不是不想帮，而是作为一个局外人且并没有太多的感情因素，无法很全面的对别人的感情做出一个客观的建议。然而被人误解确实是一件很难受的事情，像是被人用被子蒙住然后面对污蔑你的人任人指骂，你却无法或者无从进行反驳。<code>我能做的是，清楚自己想要什么，清楚自己做什么，不做任何解释，将来也不要为现在的决定后悔。</code>这篇文章也是让我压抑在自己内心，每日无时无刻会想起的事情有一个实体的抒发，毕竟屏幕前的你并不会认识我，对你来说也是又一个故事而已。如果有幸你能看到这里，那就希望你拥有一段属于自己的美好的爱情把。</p>
<p>-- 2025/06/09 1:20</p> <hr> <a href=https://blog-orcin-five-66.vercel.app>Han's 世界</a> <p>记录自己的当下</p>  <p>作者Han</p> <p>2025 June 9th发布</p>]]></content:encoded>
            <enclosure url="https://blog-orcin-five-66.vercel.app/static/photos/MyBadLove/MyBadLove1.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[瞬间]]></title>
            <link>https://blog-orcin-five-66.vercel.app/blog/randomshooting</link>
            <guid>https://blog-orcin-five-66.vercel.app/blog/randomshooting</guid>
            <pubDate>Sat, 07 Jun 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[定格生活中的某一瞬间]]></description>
            <content:encoded><![CDATA[<p>定格生活中的某一瞬间</p> <hr> <h1 id="2025-07-20-饭甑尖">2025-07-20 饭甑尖</h1>
<p>第一次尝试重装，还背了一个大西瓜 哈哈哈哈。<br>

P1: 崖壁上伴随着晚霞准备晚餐，丰盛的像是来度假了。<br>

P2: 幸好选择背风口,但整晚的风吹的让我无法入眠，像是身处在台风眼之中。莫名的担心山顶的兄弟是否顶的住， -- 第二天问了下，凌晨下撤了，山顶的风大的帐篷撑不住了。恐怖的风<br>

P3: 入手一段时间的摩卡壶，第一次进行了尝试。 -- 嗯，还不错，就是煮出来有点像中药，-/.-</p>
<div class="rehype-figure-container"><figure class="rehype-figure"><img src="/static/photos/RandomShooting/20250720fanzengjian1.jpg" alt="崖壁晚霞"><figcaption>崖壁晚霞</figcaption></figure><figure class="rehype-figure"><img src="/static/photos/RandomShooting/20250720fanzengjian2.jpg" alt="第一次帐篷过夜呢"><figcaption>第一次帐篷过夜呢</figcaption></figure><figure class="rehype-figure"><img src="/static/photos/RandomShooting/20250720fanzengjian3.jpg" alt="户外人的精神食粮"><figcaption>户外人的精神食粮</figcaption></figure></div>
<h1 id="2025-07-07-南太行">2025-07-07 南太行</h1>
<p>P1: 顶着高温一天走了20多公里，断层式垂直耸立的山体也是第一次感受，最后的绝望坡确实让人很绝望，几乎是爬几步歇一下，走完直接两腿报废。<br>

P2: 照片始终无法表现出肉眼看到的这一幕<br>

P3: 冲完澡，晚饭过后，散步到村口。之前虽未谋面的一帮人，因为一次徒步结识，一个话题接着一个话题的聊着。<code>微风、傍晚、蛙鸣、朋友、闲聊，直至月光皎洁。</code>我无法确切的描述出这种感受，这天晚上只希望时间可以慢一些，因为我不知道能否还会有如此感受。</p>
<div class="rehype-figure-container"><figure class="rehype-figure"><img src="/static/photos/RandomShooting/20250707nantaixing1.jpg" alt="苦中做乐"><figcaption>苦中做乐</figcaption></figure><figure class="rehype-figure"><img src="/static/photos/RandomShooting/20250707nantaixing2.jpg" alt="像是一幅画"><figcaption>像是一幅画</figcaption></figure><figure class="rehype-figure"><img src="/static/photos/RandomShooting/20250707nantaixing3.jpg" alt="盛夏的傍晚"><figcaption>盛夏的傍晚</figcaption></figure></div>
<h1 id="2025-06-07-花">2025-06-07 花</h1>
<p>今天周六，去4s店把车拿回来，顺道去盒马逛了圈买一些食材。看到有鲜花卖，所以... 还不赖-.-</p>
<figure class="rehype-figure"><img src="/static/photos/RandomShooting/20250607flow1.jpg" alt="this is flow" title="Flow"><figcaption>this is flow</figcaption></figure> <hr> <a href=https://blog-orcin-five-66.vercel.app>Han's 世界</a> <p>记录自己的当下</p>  <p>作者Han</p> <p>2025 June 7th发布</p>]]></content:encoded>
            <enclosure url="https://blog-orcin-five-66.vercel.app/og?title=瞬间" length="0" type="image//og"/>
        </item>
    </channel>
</rss>