WordPress 集成 Elasticsearch 搜索WordPress 集成 Elasticsearch 搜索WordPress 集成 Elasticsearch 搜索WordPress 集成 Elasticsearch 搜索
  • 文章
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容

WordPress 集成 Elasticsearch 搜索

发表 admin at 2025年9月21日
类别
  • 文章
标签
在 WordPress 环境中集成 Elasticsearch,核心是通过 WordPress 插件 桥接 Elasticsearch 服务,替换 WordPress 默认的 MariaDB 模糊搜索(低效),实现高效、精准的全文检索。 以下是完整实施方案,分步骤说明关键操作与配置。

方案架构与核心组件

各组件的角色:
组件 作用 核心需求
Elasticsearch 提供全文检索服务,存储 WordPress 索引数据 需与 WordPress 插件版本兼容(如 ES 7.x/8.x)
WordPress 插件 桥接 WP 与 ES(数据同步、搜索请求转发) 推荐 ElasticPress(功能全、维护活跃)

前置准备:

安装并配置 Elasticsearch

Elasticsearch(简称 ES)是核心检索服务,需先独立部署并确保可访问。

安装 Elasticsearch

Elasticsearch 安装软件包

Format Description Instructions
Linux and MacOS tar.gz archives The tar.gz archives are available for installation on any Linux distribution and MacOS. Install Elasticsearch from archive on Linux or MacOS
Windows .zip archive The zip archive is suitable for installation on Windows. Install Elasticsearch with .zip on Windows
deb The deb package is suitable for Debian, Ubuntu, and other Debian-based systems. Debian packages can be downloaded from the Elasticsearch website or from our Debian repository. Install Elasticsearch with Debian Package
rpm The rpm package is suitable for installation on Red Hat, Centos, SLES, OpenSuSE and other RPM-based systems. RPM packages can be downloaded from the Elasticsearch website or from our RPM repository. Install Elasticsearch with RPM

使用 Debian 软件包安装 Elasticsearch

自管理部署

Elasticsearch 的 Debian 软件包可在 Elasticsearch 下载页面 获取;其他版本可在 过往版本页面 获取。
注意:Elasticsearch 包含来自 JDK 维护者(基于 GPLv2+CE 协议)的捆绑版 OpenJDK。若需使用自定义 Java 版本,请参考 JVM 版本要求。

安装前准备

安装 Elasticsearch 前,请完成以下操作:

禁用 Linux 系统交换文件

Elasticsearch 依赖 JVM 堆内存运行,若内存被交换到磁盘(swap),会导致 IO 性能骤降,甚至引发服务响应超时、崩溃。官方明确要求生产环境禁用交换。 禁用交换后,若系统物理内存不足,可能触发 OOM(Out Of Memory) killer 杀死占用内存最高的进程(如 Elasticsearch)。需确保系统物理内存充足(至少满足 Elasticsearch JVM 堆内存需求,建议 JVM 堆内存不超过物理内存的 50%)。
  • 执行命令禁用所有交换分区 / 文件:bash
    sudo swapoff -a
    
  • 修改 /etc/fstab 文件(系统启动时自动挂载分区的配置文件),注释掉所有交换相关配置:
    • 编辑 /etc/fstab 文件:bash
      sudo vim /etc/fstab
      
    • 注释交换相关行:
      在文件中找到所有包含 swap 关键字的行,在行首添加 # 注释。
      示例(注释后): ini
      # /dev/mapper/ubuntu--vg-swap_1  swap  swap  defaults  0  0  # 已注释交换分区
      # /swapfile                      swap  swap  defaults  0  0  # 已注释交换文件
      
  • (可选)删除交换文件:
    若系统使用的是交换文件(如 /swapfile),注释配置后可删除该文件释放磁盘空间: bash
    sudo rm -f /swapfile
    
  • 验证禁用:
    • 重启系统:bash
      sudo reboot
      
    • 重启后查看交换状态
      # 查看交换空间使用情况,若输出均为 0 表示禁用成功
      free -h
      
      生效后预期输出(Swap 行的 used 为 0): plaintext
                   total        used        free      shared  buff/cache   available
      Mem:           31Gi       2.5Gi        26Gi       152Mi       2.4Gi        28Gi
      Swap:          15Gi          0B        15Gi  # used 为 0,说明交换已禁用
      

导入 Elasticsearch PGP 密钥

执行以下命令下载并安装公钥: bash
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

安装 Elasticsearch

从 APT 仓库安装
在 Debian 系统中,可能需要先安装 apt-transport-https 软件包: bash
sudo apt-get install apt-transport-https
将仓库定义保存到 /etc/apt/sources.list.d/elastic-9.x.list: bash
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-9.x.list
安装 Elasticsearch Debian 软件包: bash
sudo apt-get update && sudo apt-get install elasticsearch
注意:在基于 systemd 的发行版中,安装脚本会尝试设置内核参数(如 vm.max_map_count)。若需跳过此步骤,可屏蔽 systemd-sysctl.service 单元。

配置节点以支持网络连接

Elasticsearch 首次启动时,安全自动配置流程会将 HTTP 层绑定到 0.0.0.0,但仅将传输层绑定到 localhost。此设计可确保默认启用安全功能的单节点集群无需额外配置即可启动。
  • 注意,安全自动配置已添加http.host: 0.0.0.0到您的elasticsearch.yml配置文件中,这将覆盖 HTTP 流量的默认设置。此0.0.0.0设置使 Elasticsearch 能够监听所有可用网络接口上的HTTP 客户端连接。
  • 若运行单节点集群,可跳过此步骤,直接进入下一步。

启用系统索引自动创建功能

提示:仅当之前修改过 action.auto_create_index 的默认值时,才需执行此步骤。

通过 systemd 运行 Elasticsearch

配置开机自启
执行以下命令,配置 Elasticsearch 在系统启动时自动运行: bash
sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable elasticsearch.service
启动与停止服务
  • 启动 Elasticsearch: bash
    sudo systemctl start elasticsearch.service
    
  • 停止 Elasticsearch: bash
    sudo systemctl stop elasticsearch.service
    
上述命令不会反馈 Elasticsearch 的启动结果,相关日志会记录在 /var/log/elasticsearch/ 目录下。
密钥库密码配置(如需)
若 Elasticsearch 密钥库已设置密码,需通过本地文件和 systemd 环境变量向 systemd 提供密钥库密码。该本地文件需做好权限保护,Elasticsearch 启动后可安全删除。 bash
echo "keystore_password" > /path/to/my_pwd_file.tmp
chmod 600 /path/to/my_pwd_file.tmp
sudo systemctl set-environment ES_KEYSTORE_PASSPHRASE_FILE=/path/to/my_pwd_file.tmp
sudo systemctl start elasticsearch.service
配置 systemd 日志记录
默认情况下,Elasticsearch 服务不会向 systemd 日志(journal)输出信息。若需启用 journalctl 日志记录,需从 elasticsearch.service 文件的 ExecStart 命令行中移除 --quiet 选项。 启用 systemd 日志后,可通过以下 journalctl 命令查看日志:
  • 实时查看日志: bash
    sudo journalctl -f
    
  • 查看 Elasticsearch 服务的所有日志: bash
    sudo journalctl --unit elasticsearch
    
  • 查看指定时间后 Elasticsearch 服务的日志(示例时间为 2016-10-30 18:17:16): bash
    sudo journalctl --unit elasticsearch --since  "2016-10-30 18:17:16"
    
更多命令选项可参考 man journalctl 或 systemd journalctl 文档。
旧版本 systemd 的启动超时问题
默认情况下,Elasticsearch 会将 systemd 的 TimeoutStartSec 参数设为 900s(900 秒):
  • 若 systemd 版本 ≥ 238,Elasticsearch 可自动延长启动超时时间,直至启动完成(即使超过 900 秒);
  • 若 systemd 版本 < 238,不支持超时延长机制,若 Elasticsearch 未在 900 秒内完全启动,systemd 会终止其进程。
进程被终止时,Elasticsearch 日志会显示 “启动后不久正常关闭”: plaintext
[2022-01-31T01:22:31,077][INFO ][o.e.n.Node               ] [instance-0000000123] starting ...
...
[2022-01-31T01:37:15,077][INFO ][o.e.n.Node               ] [instance-0000000123] stopping ...
而 systemd 日志会显示 “启动超时”: plaintext
Jan 31 01:22:30 debian systemd[1]: Starting Elasticsearch...
Jan 31 01:37:15 debian systemd[1]: elasticsearch.service: Start operation timed out. Terminating.
Jan 31 01:37:15 debian systemd[1]: elasticsearch.service: Main process exited, code=killed, status=15/TERM
Jan 31 01:37:15 debian systemd[1]: elasticsearch.service: Failed with result 'timeout'.
Jan 31 01:37:15 debian systemd[1]: Failed to start Elasticsearch.
解决方法:
  • 推荐将 systemd 升级至 238 及以上版本;
  • 临时解决方案:延长 TimeoutStartSec 参数的值。

Systemd 配置

在使用systemd的系统上使用 RPM 或 Debian 包时,必须通过 systemd 指定系统限制。 systemd 服务文件 ( /usr/lib/systemd/system/elasticsearch.service) 包含默认应用的限制。 要覆盖它们,需添加一个名为的文件/etc/systemd/system/elasticsearch.service.d/override.conf(或者,您可以运行sudo systemctl edit elasticsearch该文件,它将自动在默认编辑器中打开)。在此文件中设置任何更改。

创建 override.conf 文件

bash
# 确保目录存在
sudo mkdir -p /etc/systemd/system/elasticsearch.service.d/

# 编辑配置文件
sudo vim /etc/systemd/system/elasticsearch.service.d/override.conf

编辑 override.conf 文件

  • 为 Elasticsearch 设置:
    • 进程允许打开的最大文件描述符(file descriptors) 的最大数量LimitNOFILE=65535,每个进程进程能打开的文件描述符数量默认有上限(通常为 1024 或 4096)。
    • 进程可以创建的最大进程数(或线程数)LimitNPROC=4096,对于 Elasticsearch 这类多线程应用,合理设置该参数可避免因进程 / 线程数量失控导致的系统资源耗尽问题,避免影响其他系统服务。
    • 解除 内存锁定(memory locking) 的限制LimitMEMLOCK=infinity,允许 Elasticsearch 进程 无限制地锁定内存(将进程使用的内存页锁定在物理内存中,避免被操作系统交换到磁盘的交换分区 / 文件)。
    • 解除进程的地址空间(Address Space)限制LimitAS=infinity,允许其根据需求使用系统可用的虚拟内存资源(只要系统有足够的物理内存或 swap)。虚拟地址空间是操作系统为进程分配的内存地址范围,是逻辑上的内存容量。
示例:
ini
[Service]
LimitNOFILE=65535          # 文件描述符限制
LimitMEMLOCK=infinity      # 内存锁定限制
LimitNPROC=4096            # 进程/线程数限制
LimitAS=infinity           # 解除地址空间限制

生效配置

bash
# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 重启 Elasticsearch 服务
sudo systemctl restart elasticsearch.service

验证配置是否生效

  • 验证 LimitNOFILE=65535(文件描述符限制)
    • 查看 Elasticsearch 进程的文件描述符限制:bash
      # 获取 Elasticsearch 进程 ID(PID)
      ES_PID=$(pgrep -f elasticsearch)
      
      # 查看该进程的文件描述符限制
      cat /proc/$ES_PID/limits | grep "Open files"
      
    • 若配置生效,输出应显示:plaintext
      Max open files            65535                65535                files
      
  • 验证 LimitMEMLOCK=infinity(内存锁定限制) bash
    # 获取 Elasticsearch 进程 ID(PID)
    ES_PID=$(pgrep -f elasticsearch)
    
    # 查看该进程的内存锁定限制
    cat /proc/$ES_PID/limits | grep "Max locked memory"
    
    若配置生效,输出应显示: plaintext
    Max locked memory         unlimited            unlimited            bytes
    
  • 验证 LimitNPROC=4096(进程 / 线程数限制) bash
    # 获取 Elasticsearch 进程 ID(PID)
    ES_PID=$(pgrep -f elasticsearch)
    
    # 查看该进程的最大进程数限制
    cat /proc/$ES_PID/limits | grep "Max processes"
    
    若配置生效,输出应显示: plaintext
    Max processes             4096                 4096                 processes
    
  • 验证 LimitAS=infinity(地址空间限制) bash
    # 获取 Elasticsearch 进程 ID(PID)
    ES_PID=$(pgrep -f elasticsearch)
    
    # 查看该进程的地址空间限制
    cat /proc/$ES_PID/limits | grep "Address space"
    
    若配置生效,输出应显示: plaintext
    Address space limit        unlimited            unlimited            bytes
    

说明

  • 所有验证均通过 /proc/<PID>/limits 文件实现,该文件记录了进程的所有系统资源限制;
  • 每个配置项对应 grep 过滤的关键词(如 Max locked memory 对应 LimitMEMLOCK);
  • 输出结果中,第二列是软限制(进程可自行调整的上限),第三列是硬限制(强制上限),两者一致表示配置生效。
启动时的安全配置
Elasticsearch 首次启动时,会自动完成以下安全配置:
  • 为传输层和 HTTP 层生成 TLS 证书;
  • 在 elasticsearch.yml 中应用 TLS 配置;
  • 生成注册令牌,用于 Kibana 与 Elasticsearch 的安全连接。
后续启动 Kibana 时,输入该注册令牌(有效期 30 分钟)即可:令牌会自动应用 Elasticsearch 集群的安全设置,通过内置的 kibana 服务账号向 Elasticsearch 认证,并将安全配置写入 kibana.yml。
注意:在以下场景中,安全配置无法自动完成:
  • 节点启动时检测到该节点已属于某个集群;
  • 安全功能已配置或被显式禁用。

重置 elastic 超级用户密码

由于 Elasticsearch 通过 systemd 运行(而非终端),首次启动时不会输出 elastic 超级用户的密码。需使用 elasticsearch-reset-password 工具设置该用户密码,整个集群只需执行一次,且可在第一个节点启动后立即操作: bash
bin/elasticsearch-reset-password -u elastic
建议将 elastic 密码存储为 shell 的环境变量,示例如下: bash
export ELASTIC_PASSWORD="your_password"
若 Elasticsearch 密钥库已设置密码,执行上述命令时会提示输入密钥库密码。详情可参考 安全设置文档。 如需了解如何重置该密码,可参考 自管理集群中为原生用户和内置用户设置密码。

验证 Elasticsearch 运行状态

向 localhost 的 9200 端口发送 HTTPS 请求,可测试 Elasticsearch 节点是否正常运行: bash
curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:$ELASTIC_PASSWORD https://localhost:9200
  • curl:命令行 HTTP/HTTPS 请求工具。
  • --cacert /etc/elasticsearch/certs/http_ca.crt:指定用于验证服务器证书的 CA 根证书路径。
    • Elasticsearch 安装时会自动生成自签名 CA 证书(http_ca.crt),位于 certs 目录下。
    • 该参数让 curl 信任此 CA 签发的服务器证书。
  • -u elastic:$ELASTIC_PASSWORD:指定 HTTP 基本认证的用户名和密码。
    • elastic 是默认超级用户。
    • $ELASTIC_PASSWORD 是存储密码的环境变量(需提前通过 export ELASTIC_PASSWORD="your_password" 定义)。或将 $ELASTIC_PASSWORD 替换为 elastic 超级用户的密码;
  • https://localhost:9200:Elasticsearch 服务的 HTTPS 访问地址(本地主机 + 默认端口 9200)。
    • 必须使用 https 协议,否则请求会失败。
或
curl -k -u elastic:$ELASTIC_PASSWORD https://localhost:9200
  • -k(--insecure):允许 curl 跳过对 SSL 证书的验证。
请求成功后,会返回类似以下的响应: json
{
  "name" : "ubuntu-vm",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "zpMiuMM7QISFXmWxeKxoIQ",
  "version" : {
    "number" : "9.1.2",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "ca1a70216fbdefbef3c65b1dff04903ea5964ef5",
    "build_date" : "2025-08-11T15:04:41.449624592Z",
    "build_snapshot" : false,
    "lucene_version" : "10.2.2",
    "minimum_wire_compatibility_version" : "8.19.0",
    "minimum_index_compatibility_version" : "8.0.0"
  },
  "tagline" : "You Know, for Search"
}

步骤 8(仅多节点集群):更新配置文件

部署多节点集群时,elasticsearch-reconfigure-node 工具会将所有现有节点添加到新注册节点的 discovery.seed_hosts 配置中。但需返回集群中的所有节点,手动编辑配置,确保每个节点重启后能正常重新加入集群。
  • 若运行单节点集群,可跳过此步骤,直接进入下一步。

配置 Elasticsearch

配置文件目录权限
/etc/elasticsearch 目录包含 Elasticsearch 的默认运行时配置,软件包安装后,该目录及所含文件的所有者会设为 root:elasticsearch(root 用户,elasticsearch 组)。 /etc/elasticsearch 目录启用了 setgid 标志,确保组权限可继承,Elasticsearch 能读取其中的所有文件和子目录;所有文件和子目录会继承 root:elasticsearch 的所有权。在该目录或其子目录中执行命令(如 elasticsearch-keystore 工具)时,需具备 root:elasticsearch 权限。
主配置文件
Elasticsearch 默认从 /etc/elasticsearch/elasticsearch.yml 文件加载配置,配置文件格式说明可参考 配置 Elasticsearch。
系统环境变量配置文件
Debian 软件包还提供了系统级配置文件,路径如下: plaintext
/etc/default/elasticsearch
该文件中可设置以下参数:
参数 说明
ES_JAVA_HOME 设置自定义 Java 路径(若需使用非捆绑版 JDK)。
ES_PATH_CONF 配置文件目录(需包含 elasticsearch.yml、jvm.options 和 log4j2.properties 文件),默认值为 /etc/elasticsearch。
ES_JAVA_OPTS 需额外应用的 JVM 系统属性。
RESTART_ON_UPGRADE 配置软件包升级时是否自动重启 Elasticsearch,默认值为 false(需手动重启,避免集群升级时因分片持续重分配导致网络流量过高、响应延迟增加)。
注意:基于 systemd 的发行版要求通过 systemd 配置系统资源限制,而非 /etc/default/elasticsearch 文件。详情可参考 Systemd 配置。

客户端连接 Elasticsearch

Elasticsearch 首次启动时,会自动为 HTTP 层配置 TLS,生成的 CA 证书存储在以下路径: plaintext
/etc/elasticsearch/certs/http_ca.crt
证书的十六进制编码 SHA-256 指纹也会输出到终端。所有连接 Elasticsearch 的客户端(如 Elasticsearch 客户端、Beats、独立 Elastic Agent、Logstash)均需验证是否信任 Elasticsearch 用于 HTTPS 的证书:
  • Fleet Server 和 Fleet 管理的 Elastic Agent 会自动配置信任该 CA 证书;
  • 其他客户端可通过 “验证 CA 证书指纹” 或 “直接使用 CA 证书” 两种方式建立信任。
若已完成自动配置,仍可通过以下方式获取证书指纹或复制 CA 证书。
方式 1:使用 CA 证书指纹
  • 复制 Elasticsearch 启动时终端输出的指纹值,配置客户端通过该指纹验证信任;
  • 若自动配置已完成,可通过以下命令获取证书指纹(路径为 HTTP 层自动生成的 CA 证书): bash
    openssl x509 -fingerprint -sha256 -in config/certs/http_ca.crt
    

    命令会返回证书信息(含指纹),其中 issuer(颁发者)应为 Elasticsearch security auto-configuration HTTP CA,示例如下: plaintext
    issuer= /CN=Elasticsearch security auto-configuration HTTP CA
    SHA256 Fingerprint=<fingerprint>
    
方式 2:使用 CA 证书
若客户端库不支持指纹验证,可直接使用自动生成的 CA 证书:
  • 每个 Elasticsearch 节点的 CA 证书路径为 /etc/elasticsearch/certs/http_ca.crt;
  • 将 http_ca.crt 文件复制到客户端所在机器,配置客户端通过该证书建立信任。

Debian 软件包的目录结构

Debian 软件包将配置文件、日志、数据目录等按 Debian 系统规范放置,具体路径如下:
类型 说明 默认路径 配置参数
home Elasticsearch 主目录(即 $ES_HOME) /usr/share/elasticsearch -
bin 二进制脚本目录(含 elasticsearch 节点启动脚本、elasticsearch-plugin 插件安装脚本等) /usr/share/elasticsearch/bin -
conf 主配置文件目录(含 elasticsearch.yml) /etc/elasticsearch ES_PATH_CONF
conf 环境变量配置文件(含堆大小、文件描述符等) /etc/default/elasticsearch -
conf 自动生成的传输层和 HTTP 层 TLS 密钥与证书目录 /etc/elasticsearch/certs -
data 节点上所有索引 / 分片的数据文件存储目录 /var/lib/elasticsearch path.data
jdk 用于运行 Elasticsearch 的捆绑版 JDK,可通过 /etc/default/elasticsearch 中的 ES_JAVA_HOME 环境变量覆盖 /usr/share/elasticsearch/jdk -
logs 日志文件存储目录 /var/log/elasticsearch path.logs
plugins 插件文件目录(每个插件对应一个子目录) /usr/share/elasticsearch/plugins -
repo 共享文件系统仓库目录(可配置多个路径,文件系统仓库可放在任意指定目录的子目录中) 未配置(需手动设置) path.repo

后续步骤

当前已搭建 Elasticsearch 测试环境,若需用于正式开发或生产环境,还需完成以下额外配置:
  • 学习 如何配置 Elasticsearch;
  • 配置 重要的 Elasticsearch 设置。
要在Elasticsearch中禁用密码认证并允许HTTP访问,需要修改配置文件 /etc/elasticsearch/elasticsearch.yml:
# 禁用安全功能
xpack.security.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false
更改后,Elasticsearch 将不再要求密码认证,并且可以通过HTTP接口访问。

了解 Elasticsearch API

Elasticsearch API https://www.elastic.co/docs/api/doc/elasticsearch/

安装 Elasticsearch 中文分词插件

IK 分词器(elasticsearch-analysis-ik)是 Elasticsearch 中最常用的中文分词插件之一,专为处理中文文本设计,能将中文句子拆分为有意义的词语(而非单个汉字),大幅提升中文搜索的准确性。

核心功能

  • 两种分词模式
    • ik_max_word:最细粒度分词(尽可能拆分多的词语)
      例:“中华人民共和国” → 中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国等
    • ik_smart:粗粒度分词(仅做最基本拆分)
      例:“中华人民共和国” → 中华人民共和国
  • 内置词典
    包含基础中文词汇、常见姓氏、地名、机构名等,覆盖日常用语场景。
  • 自定义扩展
    支持添加自定义词典(如行业术语、专有名词)、停用词(过滤无意义词汇,如 “的”“了”)。
  • 动态更新词典
    可配置远程词典(通过 HTTP 访问),实现无需重启 Elasticsearch 即可更新词汇。

使用场景

  • 中文全文检索(如电商商品搜索、新闻内容检索)
  • 文本分析(如舆情监控、用户评论分词)
  • 日志处理(对中文日志进行结构化分析)
  • 中英文混合的文本
    • IK 分词器在解析混合文本时,会根据字符类型(中文字符、英文字母、数字、符号)自动切换处理策略:
      • 中文部分:按 ik_max_word(细粒度)或 ik_smart(粗粒度)模式拆分,遵循中文词汇逻辑(如 “我爱 Elasticsearch” 中的 “我”“爱” 会拆分为独立中文词);
      • 英文部分:完整保留英文单词(含大小写混合,如 “Elasticsearch”“IKAnalyzer”),不会拆分为单个字母;
      • 数字 / 符号:独立识别数字(如 “2024”)、英文符号(如 “-”“_”),若与英文结合(如 “v9.1.2”“user_name”),会作为整体识别。

      实际效果示例

      通过 _analyze API 测试中英文混合文本的分词结果,可直观看到处理能力:

      测试命令(使用 ik_max_word 模式)

      bash
      curl -k -u elastic:你的密码 -X POST "https://localhost:9200/_analyze" -H "Content-Type: application/json" -d '
      {
        "analyzer": "ik_max_word",
        "text": "我在学习 Elasticsearch 9.1.2 的 IK 分词器用法"
      }'
      

      关键分词结果(简化)

      json
      {
        "tokens": [
          {"token": "我", "start_offset": 0, "end_offset": 1},  // 中文单字
          {"token": "在", "start_offset": 1, "end_offset": 2},  // 中文单字
          {"token": "学习", "start_offset": 2, "end_offset": 4},  // 中文词汇
          {"token": "elasticsearch", "start_offset": 5, "end_offset": 18},  // 英文单词(自动小写)
          {"token": "9.1.2", "start_offset": 19, "end_offset": 23},  // 数字+符号组合
          {"token": "的", "start_offset": 24, "end_offset": 25},  // 中文助词
          {"token": "ik", "start_offset": 26, "end_offset": 28},  // 英文缩写
          {"token": "分词器", "start_offset": 29, "end_offset": 32},  // 中文词汇
          {"token": "用法", "start_offset": 33, "end_offset": 35}  // 中文词汇
        ]
      }
      

      注意事项

      • 英文大小写统一:IK 分词器会自动将英文单词转为小写(如示例中 “Elasticsearch”→“elasticsearch”),若需保留大小写,需通过自定义配置调整(需修改 IK 源码或结合其他插件,默认不支持);
      • 特殊符号处理:若文本含中文符号(如 “,”“。”),IK 会自动过滤(视为分隔符);若含特殊符号(如 “@”“#”),会拆分符号与前后内容(如 “user@es”→“user”“@”“es”);
      • 自定义词汇兼容:若自定义词典中包含 “中英文混合词”(如 “Elasticsearch 分词器”),需确保词汇格式正确(空格不影响,IK 会按配置识别)。
      综上,IK 分词器对中英文混合文本的处理能力满足日常需求,无需额外配置即可兼顾中文词汇拆分与英文 / 数字的完整识别,是中文场景下处理混合文本的优选方案。
在 Elasticsearch 中安装 IK 分词器(一款常用的中文分词插件),可按照以下步骤操作:

安装前提条件

  • 确保 Elasticsearch 已正常安装并运行
  • IK 分词器版本必须与 Elasticsearch 版本完全一致(例如 Elasticsearch 9.1.2 需对应 IK 9.1.2)
  • 安装前建议停止 Elasticsearch 服务(非必需,但可避免安装过程中出现冲突)

安装步骤

方法 1:通过 Elasticsearch 插件命令安装(推荐)

  • 执行 Elasticsearch 的插件安装命令,指定与 Elasticsearch 版本(例如 9.1.2)匹配的 IK 分词器: bash
    sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/9.1.2
  • 安装过程中会提示是否继续,输入 y 确认: plaintext
    Continue with installation? [y/N]y
    -> Installed analysis-ik
    -> Please restart Elasticsearch to activate any plugins installed
    

方法 2:手动下载安装(适用于网络受限环境)

  • 获取打包插件

    下载与 Elasticsearch 版本匹配的打包插件:https://release.infinilabs.com/

  • 创建 Elasticsearch 插件目录(默认路径为 /usr/share/elasticsearch/plugins/analysis-ik): bash
    sudo mkdir -p /usr/share/elasticsearch/plugins/analysis-ik
    
  • 解压 zip 包到插件目录: bash
    sudo unzip elasticsearch-analysis-ik-{版本号}.zip -d /usr/share/elasticsearch/plugins/analysis-ik/
    

验证安装

  • 启动(或重启)Elasticsearch 服务: bash
    sudo systemctl restart elasticsearch
    
  • 通过 API 测试分词效果: bash
    curl -k -u elastic:你的密码 -X POST "https://localhost:9200/_analyze" -H "Content-Type: application/json" -d '
    {
      "analyzer": "ik_max_word",
      "text": "我爱中国"
    }'
    
    成功响应会返回分词结果: json
    {
      "tokens": [
        {"token": "我", "start_offset": 0, "end_offset": 1, ...},
        {"token": "爱", "start_offset": 1, "end_offset": 2, ...},
        {"token": "中国", "start_offset": 2, "end_offset": 4, ...}
      ]
    }
    

IK 分词器常用模式

  • ik_max_word:最细粒度分词(如 “中华人民共和国” 会拆分为 “中华人民共和国”“中华人民”“中华” 等)
  • ik_smart:粗粒度分词(如 “中华人民共和国” 仅拆分为 “中华人民共和国”)

自定义词典(可选)

若需添加自定义词汇(如行业术语),可修改 IK 分词器的配置:
  • 进入 IK 插件的配置目录: bash
    cd /usr/share/elasticsearch/plugins/analysis-ik/config
    
  • 创建自定义词典文件(例如 custom.dic),每行添加一个词汇: bash
    sudo vim custom.dic
    
    内容示例: plaintext
    人工智能
    机器学习
    
  • 编辑 IKAnalyzer.cfg.xml,在 <entry key="ext_dict"> 中添加自定义词典文件名:xml
    <properties>
      <comment>IK Analyzer 扩展配置</comment>
      <entry key="ext_dict">custom.dic</entry> <!-- 新增此行 -->
    </properties>
    
  • 重启 Elasticsearch 使配置生效: bash
    sudo systemctl restart elasticsearch
    
通过以上步骤,即可在 Elasticsearch 中成功安装并使用 IK 分词器,实现更精准的中文分词处理。

基本使用示例

创建索引时指定 IK 分词器

bash
# 创建一个使用 ik_max_word 作为默认分词器的索引
curl -k -u elastic:密码 -X PUT "https://localhost:9200/my_index" -H "Content-Type: application/json" -d '
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "ik_max_word"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "content": {
        "type": "text",
        "analyzer": "ik_max_word",  # 字段级指定分词器
        "search_analyzer": "ik_smart"  # 搜索时使用粗粒度分词
      }
    }
  }
}'
2. 测试分词效果 bash
# 测试 ik_max_word 分词
curl -k -u elastic:密码 -X POST "https://localhost:9200/_analyze" -H "Content-Type: application/json" -d '
{
  "analyzer": "ik_max_word",
  "text": " Elasticsearch 是一个分布式搜索引擎 "
}'
响应结果(简化): json
{
  "tokens": [
    {"token": "elasticsearch", "start_offset": 1, "end_offset": 14, ...},
    {"token": "是", "start_offset": 15, "end_offset": 16, ...},
    {"token": "一个", "start_offset": 17, "end_offset": 19, ...},
    {"token": "分布式", "start_offset": 20, "end_offset": 23, ...},
    {"token": "搜索", "start_offset": 23, "end_offset": 25, ...},
    {"token": "引擎", "start_offset": 25, "end_offset": 27, ...}
  ]
}
高级配置:自定义词典

本地自定义词典

  • 进入 IK 插件配置目录(以 Debian 安装为例): bash
    cd /usr/share/elasticsearch/plugins/analysis-ik/config
  • 创建自定义词典文件(如 tech_dict.dic): bash
    sudo vim tech_dict.dic
    
    内容(每行一个词): plaintext
    人工智能
    机器学习
    大模型
  • 编辑 IKAnalyzer.cfg.xml,添加自定义词典:xml
    <properties>
      <entry key="ext_dict">tech_dict.dic</entry>  <!-- 多个词典用逗号分隔 -->
      <entry key="ext_stopwords">stopword.dic</entry>  <!-- 自定义停用词 -->
    </properties>
    
  • 重启 Elasticsearch 生效: bash
    sudo systemctl restart elasticsearch
    

远程词典(动态更新)

在 IKAnalyzer.cfg.xml 中配置远程词典 URL(支持 HTTP/HTTPS): xml
<properties>
  <entry key="remote_ext_dict">https://example.com/remote_dict.dic</entry>
  <entry key="remote_ext_stopwords">https://example.com/remote_stop.dic</entry>
</properties>
IK 分词器会定期检查远程文件的更新(默认间隔 60 秒),无需重启服务即可加载新词。

常见问题

  • 版本不兼容
    IK 分词器版本必须与 Elasticsearch 完全一致(如 Elasticsearch 8.10.4 需对应 IK 8.10.4),否则会导致启动失败。
  • 分词效果不符合预期
    • 检查是否使用了正确的分词模式(ik_max_word/ik_smart)
    • 通过 _analyze API 调试分词结果,补充自定义词汇
  • 自定义词典不生效
    • 确保词典文件编码为 UTF-8 无 BOM(Windows 系统需注意)
    • 检查文件权限,确保 Elasticsearch 进程可读取
通过合理配置 IK 分词器,能显著提升 Elasticsearch 对中文内容的处理能力,是中文场景下不可或缺的插件。

安装 Kibana

自管理部署
Kibana 为所有 Elastic 解决方案提供用户界面,是一款功能强大的工具,可用于数据可视化与分析,以及 Elastic Stack 的管理和监控。尽管使用 Elasticsearch 并非必须搭配 Kibana,但在大多数使用场景中,Kibana 是必不可少的。 Kibana 基于 Node.js 运行,官方已为这些平台包含所需的 Node.js 二进制文件,不支持将 Kibana 与独立维护的 Node.js 版本搭配使用。 安装 Elastic Stack 时,整个技术栈的所有组件必须使用相同版本。例如,若使用 Elasticsearch 9.1.2,那么 Beats、APM Server、Elasticsearch Hadoop、Kibana 和 Logstash 也需安装 9.1.2 版本。

安装顺序

若在自管理集群中部署 Elastic Stack,需按以下顺序安装所需的 Elastic Stack 产品:
  • Elasticsearch
  • Kibana

Kibana 安装包格式

Kibana 提供以下几种格式的安装包:
格式 说明 操作指南
tar.gz 适用于 Linux 和 Darwin 系统,是快速上手 Kibana 的首选安装包格式 Install from archive on Linux or macOS
zip Windows 系统唯一支持的安装包格式 Install on Windows
deb 适用于 Debian、Ubuntu 及其他基于 Debian 的系统,可从 Elastic 官网或 Debian 仓库下载 Install with Debian package
rpm 适用于 Red Hat、SLES、OpenSuSE 及其他基于 RPM 的系统,可从 Elastic 官网或 RPM 仓库下载 Install with RPM
docker 提供用于以 Docker 容器形式运行 Kibana 的镜像,可从 Elastic Docker 仓库下载 Running Kibana on Docker

默认端口

下表列出了运行 Elasticsearch 集群所需的可访问端口。其中,Elasticsearch 的 REST 接口和 Kibana 界面需对外部用户开放,集群才能正常使用;传输 API(Transport API)需在集群内的 Elasticsearch 节点之间保持可访问,同时也要对使用传输 API 的外部客户端开放。 默认情况下,Elasticsearch 会尝试监听指定端口范围内的第一个端口,若该端口已被占用,则尝试下一个端口。这些配置可在对应的配置文件中修改。
端口 访问类型 用途 配置参数
及以上 HTTP(REST) Elasticsearch 的 REST API 接口,是外部来源(包括 Kibana、Logstash)访问集群的主要接口 Elasticsearch http.port
及以上 TCP 传输 API 接口,用于集群内节点间通信,以及客户端通过传输 API(Java 客户端)访问集群 Elasticsearch transport.port
5601 HTTP Kibana 的默认访问端口 Kibana server.port
Elastic Stack 的可选组件可能需要额外端口,具体可参考对应组件的安装指南。

使用 Debian 软件包安装 Kibana

自管理部署

Kibana 的 Debian 软件包可在 Kibana 下载页面 获取;其他版本可在 过往版本页面 获取。

导入 Elastic PGP 密钥

执行以下命令下载并安装公钥: bash
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

安装 Kibana

从 APT 仓库安装
在 Debian 系统中,可能需要先安装 apt-transport-https 软件包: bash
sudo apt-get install apt-transport-https
将仓库定义保存到 /etc/apt/sources.list.d/elastic-9.x.list: bash
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-9.x.list
安装 Kibana Debian 软件包: bash
sudo apt-get update && sudo apt-get install kibana

启动 Elasticsearch 并生成 Kibana 注册令牌

启动 Elasticsearch 服务。 首次启动第一个 Elasticsearch 节点时,系统会自动完成以下安全配置:
  • 为传输层和 HTTP 层生成 TLS 证书;
  • 在 elasticsearch.yml 中应用 TLS 配置;
  • 为 elastic 超级用户设置密码;
  • 生成注册令牌,用于 Kibana 与 Elasticsearch 的安全连接。
后续启动 Kibana 时,输入该注册令牌即可(令牌有效期为 30 分钟)。该令牌会自动应用 Elasticsearch 集群的安全设置,通过内置的 kibana 服务账号向 Elasticsearch 认证,并将安全配置写入 kibana.yml。
注意:在以下场景中,安全配置无法自动完成:
  • 节点启动时检测到该节点已属于某个集群;
  • 安全功能已配置或被显式禁用。
若注册令牌已过期,可使用 elasticsearch-create-enrollment-token 工具重新生成 Kibana 注册令牌: bash
bin/elasticsearch-create-enrollment-token -s kibana

步骤 4(可选):配置 Kibana 支持外部访问

默认情况下,Kibana 的主机与端口配置为 localhost:5601。若需允许远程用户连接,需将 Kibana 配置为运行在可路由的外部 IP 地址,可通过编辑 kibana.yml 文件实现:
  • 用文本编辑器打开 kibana.yml;
  • 取消注释 #server.host: localhost,并将默认地址替换为 0.0.0.0(0.0.0.0 表示 Kibana 监听所有可用网络接口;生产环境中可根据需求使用静态 IP 地址):yaml
    server.host: 0.0.0.0
    
  • 保存修改并关闭编辑器。

通过 systemd 运行 Kibana

配置开机自启
执行以下命令,配置 Kibana 在系统启动时自动运行: bash
sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable kibana.service
启动与停止服务
  • 启动 Kibana: bash
    sudo systemctl start kibana.service
    
  • 停止 Kibana: bash
    sudo systemctl stop kibana.service
    
上述命令不会反馈 Kibana 的启动结果,可通过 journalctl -u kibana.service 查看日志信息。

将 Kibana 与 Elasticsearch 注册关联

  • 执行 status 命令查看 Kibana 服务详情: bash
    sudo systemctl status kibana
    
  • 在 status 命令的输出中,会显示一个包含以下信息的 URL:
    • 访问 Kibana 的主机地址;
    • 6 位验证码。
      示例输出如下:
    plaintext
    Kibana has not been configured.
    Go to http://<host>:5601/?code=<code> to get started.
    
  • 记录下验证码,然后访问上述主机地址。
    Kibana 启动可能需要 1-2 分钟,若未立即看到提示,可刷新页面。
  • Kibana 启动后,会提示输入注册令牌,粘贴之前生成的 Kibana 注册令牌,点击「Configure Elastic」(配置 Elastic)。
  • 若提示输入验证码,复制并粘贴 status 命令输出的 6 位代码,然后等待设置完成。
  • 出现「Welcome to Elastic」(欢迎使用 Elastic)页面时,输入用户名 elastic,并输入搭建第一个 Elasticsearch 节点时从安装命令输出中复制的密码,点击「Log in」(登录)。

通过配置文件配置 Kibana

Kibana 默认从 /etc/kibana/kibana.yml 文件加载配置。配置文件格式说明可参考 配置 Kibana。

Debian 软件包的目录结构

Debian 软件包将配置文件、日志、数据目录等按 Debian 系统规范放置,具体路径如下:
类型 说明 默认路径 配置参数
home Kibana 主目录(即 $KIBANA_HOME) /usr/share/kibana -
bin 二进制脚本目录(含 kibana 服务启动脚本、kibana-plugin 插件安装脚本等) /usr/share/kibana/bin -
config 配置文件目录(含 kibana.yml) /etc/kibana [KBN_PATH_CONF](configure-kibana.md)
data Kibana 及其插件写入磁盘的数据文件存储目录 /var/lib/kibana path.data
logs 日志文件存储目录 /var/log/kibana [Logging configuration](../../monitor/logging-configuration/kibana-logging.md)
plugins 插件文件目录(每个插件对应一个子目录) /usr/share/kibana/plugins -

使用 Kibana 操作 Elasticsearch

Kibana 是官方配套的 Elasticsearch 可视化和管理工具,可用于索引管理、数据查询、可视化报表、集群监控等。 以下是使用 Kibana 操作 Elasticsearch 的核心流程和常用功能:

连接 Kibana 与 Elasticsearch

  1. 前提:已安装并启动 Elasticsearch 和 Kibana(版本需一致),且 Kibana 已通过注册令牌与 Elasticsearch 关联(参考之前的安装步骤)。
  2. 访问 Kibana:
    打开浏览器,访问 http://<Kibana主机IP>:5601,使用 Elasticsearch 的 elastic 账号和密码登录。

二、核心功能使用指南

1. 数据探索与查询(Discover)
通过 Kibana 的 Discover 模块,可以可视化查询 Elasticsearch 中的数据:
  • 选择索引:左侧 “索引模式” 下拉框选择要查询的索引(首次使用需先创建索引模式,见下文)。
  • 搜索数据:
    • 顶部搜索框支持 KQL(Kibana Query Language),例如:
      • content: " Elasticsearch "(查询 content 字段包含 “Elasticsearch” 的文档)
      • age > 30 AND gender: "male"(多条件过滤)
    • 也可切换为 Lucene 语法 或 JSON 格式查询(DSL)。
  • 筛选与排序:通过左侧字段列表点击 “添加” 可快速筛选,或通过顶部 “排序” 按钮设置排序规则。
  • 查看文档:下方表格展示匹配的文档,点击文档可查看完整 JSON 结构。
2. 索引管理(Stack Management)
在 Stack Management → Index Management 中管理 Elasticsearch 索引:
  • 查看索引:显示所有索引的名称、大小、文档数、健康状态等。
  • 创建索引:点击 “Create index”,可自定义索引名称、设置分片 / 副本数、配置映射(mapping)等。
    示例:创建一个使用 IK 分词器的中文索引: json
    {
      "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 1,
        "analysis": {
          "analyzer": {
            "default": {
              "type": "custom",
              "tokenizer": "ik_max_word",
              "filter": ["lowercase"]
            }
          }
        }
      },
      "mappings": {
        "properties": {
          "title": { "type": "text" },
          "content": { "type": "text" },
          "timestamp": { "type": "date" }
        }
      }
    }
    
  • 索引模板:通过 “Index Templates” 创建模板,定义新索引的默认配置(避免重复设置)。
  • 索引生命周期管理(ILM):配置索引的自动生命周期(如滚动、归档、删除),适合日志等时序数据。
3. 可视化与仪表盘(Visualize & Dashboard)
将查询结果转化为图表,并组合成仪表盘:
  • 创建可视化:
    进入 Visualize Library,选择图表类型(如柱状图、折线图、地图等),设置 “数据源”(索引)和 “聚合方式”(如按字段分组、计算平均值等)。
    示例:统计不同类别的文档数量(使用 “Terms” 聚合)。
  • 组合仪表盘:
    在 Dashboard 中添加多个可视化图表,调整布局后保存,可实时查看数据变化(适合监控场景)。
4. 开发者工具(Dev Tools)
Dev Tools 是 Elasticsearch 开发者的核心工具,可直接编写和执行 Elasticsearch API 请求:
  • Console:左侧输入请求(支持自动补全),右侧显示响应结果,例如:
    • 查看集群健康: bash
      GET /_cluster/health
      
    • 创建文档: bash
      POST /my_index/_doc/1
      {
        "title": "Kibana 教程",
        "content": "Kibana 是 Elasticsearch 的可视化工具",
        "timestamp": "2024-08-21T00:00:00"
      }
      
    • 复杂查询(DSL): bash
      GET /my_index/_search
      {
        "query": {
          "match": {
            "content": "Elasticsearch 可视化"
          }
        }
      }
      
    • 关键操作说明
      • 请求格式:遵循 Elasticsearch API 规范,格式为 HTTP方法 /路径(如 GET /_cluster/health、PUT /索引名)。
      • 运行方式: 点击单个请求,点击右上角的三角形图标(只运行当前请求)。 按 Ctrl + Enter(Windows/Linux)运行当前光标所在的请求。
        • 如果想批量运行,可选中多个请求后再按此快捷键或点击右上角的三角形图标。
      • 自动补全:输入时会自动提示 Elasticsearch 的 API 路径、参数等,按 Tab 键可快速补全。
      • 清空与保存:可通过顶部按钮清空输入框,或保存常用请求为 “片段”(Snippets)以便下次复用。
      • 参考文档:Run API requests with Console
  • 其他工具:可查看索引模板、分析器测试(_analyze)、集群设置等。
5. 集群监控(Monitoring)
在 Stack Monitoring 中监控 Elasticsearch 集群状态:
  • 查看节点 CPU、内存、磁盘使用率;
  • 监控索引分片分布、搜索 / 写入性能;
  • 设置告警(如节点下线、磁盘空间不足时通知)。
6. 索引模式(Index Patterns)
首次使用 Discover 或 Visualize 前,需创建 索引模式(告诉 Kibana 哪些索引需要被管理):
  1. 进入 Stack Management → Index Patterns → Create index pattern;
  2. 输入索引名称(支持通配符,如 my_index* 匹配所有以 my_index 开头的索引);
  3. 选择时间字段(若有,用于时间序列分析),完成创建。

常用操作示例

  1. 通过 Kibana 测试 IK 分词器:
    在 Dev Tools 中执行: bash
    POST /_analyze
    {
      "analyzer": "ik_max_word",
      "text": "Kibana 是 Elasticsearch 的中文分词工具"
    }
    
    右侧会返回分词结果,验证 IK 分词效果。
  2. 创建仪表盘监控网站访问量:
    • 用 Visualize 创建 “按小时访问量折线图” 和 “按页面类型柱状图”;
    • 在 Dashboard 中组合这两个图表,实时监控网站流量。

四、总结

Kibana 是 Elasticsearch 的 “操作中枢”,通过它可以:
  • 用可视化界面替代复杂的 API 命令;
  • 快速构建数据报表和监控面板;
  • 调试索引配置和查询语句。
熟练使用 Kibana 能大幅提升 Elasticsearch 的使用效率,尤其适合非开发人员或需要快速分析数据的场景。

WordPress 集成 Elasticsearch

通过 ElasticPress 插件 实现桥接(功能最完善,支持自动同步、搜索权重调整)。

安装并激活 ElasticPress

  • 进入 WordPress 后台 → 插件 → 安装插件 → 搜索 ElasticPress;
  • 点击 “安装” 并 “激活”。

配置插件连接 Elasticsearch

激活后,插件会自动引导配置,或手动进入 设置 → ElasticPress:
  • 设置 Elasticsearch 主机:
    • 在 Third-Party/Self-Hosted 中的 Elasticsearch 主机 URL 中输入 Elasticsearch 地址: https://elastic:password@[Elasticsearch服务器IP]:9200(若同服务器,填 https://elastic:password@localhost:9200);
      • 以 https://user:pass@www.domain.com/path:9200 为例,这个 URL 在 HTTPS 协议中明文传输的部分仅为 “目标域名(www.domain.com)”,其他部分均为加密传输。
        • 关键细节拆解

          • 不加密的核心:SNI 中的域名(www.domain.com)
            • TLS 握手的第一步是客户端发送 “客户端问候(Client Hello)” 消息,其中会通过 SNI 字段 告知服务器:“我要访问的域名是 www.domain.com”。
            • 这一 SNI 字段的内容(仅 www.domain.com 这个域名)是 明文传输 的,攻击者可捕获到该信息,得知客户端要访问的域名,但无法获取其他数据。
            • 注意:SNI 仅包含 “域名”,不包含 URL 中的端口(9200)、路径(/path)、认证信息(user:pass)。
          • 其他相关部分的加密状态(均加密)
            • 端口(9200):URL 中的 :9200 是目标端口,会作为 HTTP 请求头的 Host 字段(格式:Host: www.domain.com:9200),随整个 HTTP 头部被 TLS 加密后传输,握手阶段不涉及端口的明文传输。
            • 路径(/path)、认证信息(user:pass):这些属于 HTTP 请求的内容(路径在请求行,认证信息在 Authorization 头),仅在 TLS 握手成功、建立加密通道后才传输,全程被 TLS 加密,握手阶段完全不涉及。
        • 虽然网络传输是加密的,但需注意:user:pass@ 形式的风险主要在于 URL 本身的存储或日志泄露(如浏览器历史记录、服务器访问日志可能记录完整 URL),而非网络传输过程。
      • 无需配置客户端信任 Elasticsearch 生成的证书。
    • 点击 “保存更改”,获取到 Elasticsearch 版本 即正常。
  • 选择同步内容:
    • 在 Select your features 中勾选需要同步到 Elasticsearch 的数据类型:如 “文章搜索”“自动建议”“受保护的内容”;
    • 点击 “索引您的内容”,即会转至“同步信息”页面,在这里,可以选择“同步的文章类型”。

同步 WordPress 数据到 Elasticsearch

ES 需先获取 WordPress 现有数据(建立索引),后续新增 / 更新内容会自动同步:
  • 在 ElasticPress Sync页,点击 “同步” 按钮(引导配置中已完成首次同步可忽略);
  • 同步进度可在页面查看,数据量较大时需耐心等待;
    • 同步完成后,可以 Status Report 页面中的 Elasticsearch Indices 部分查看生成的索引信息。
    • 验证同步结果:登录 Elasticsearch 服务器,执行命令查看索引是否生成: bash
      curl -k -u elastic:password -X GET "https://[Elasticsearch服务器IP]:9200/_cat/indices?v"
      • 假设索引名为 examplecom-post-1:
        • 查看索引的基本信息(结构、设置、映射) 使用 GET /<索引名> 命令: curl -k -u elastic:password -X GET "https://[Elasticsearch服务器IP]:9200/examplecom-post-1?pretty"
        • 只查看索引的映射(字段结构) 使用 GET /<索引名>/_mapping 命令: curl -k -u elastic:password -X GET "https://[Elasticsearch服务器IP]:9200/examplecom-post-1/_mapping?pretty"
        • 只查看索引的设置(分片、副本等) 使用 GET /<索引名>/_settings命令: curl -k -u elastic:password -X GET "https://[Elasticsearch服务器IP]:9200/examplecom-post-1/_settings?pretty"
        • 查询指定索引文档总数 使用 GET /<索引名>/_count 命令: curl -k -u elastic:password -X GET "https://[Elasticsearch服务器IP]:9200/examplecom-post-1/_count?pretty"

替换 WordPress 默认搜索

ElasticPress 自动接管 WP 默认搜索,无需设置。

ElasticPress 实现 IK 分词器配置

目前,未找到方便的 ElasticPress 实现 IK 分词器配置的解决办法。 暂时采用修改 ElasticPress 映射文件中字段级别的 analyzer 实现 IK 分词器配置: 在 WordPress 目录中找到 /wp-content/plugins/elasticpress/includes/mappings/post/7-0.php 修改'properties'下的 WordPress 文章字段,添加或修改 'analyzer' 为 'ik_max_word'。 例如:
'post_title'            => array(
	'type'   => 'text',
	'fields' => array(
		'post_title' => array(
			'type'     => 'text',
			'analyzer' => 'ik_max_word',
		),
		'raw'        => array(
			'type'         => 'keyword',
			'ignore_above' => 10922,
		),
		'sortable'   => array(
			'type'         => 'keyword',
			'ignore_above' => 10922,
			'normalizer'   => 'lowerasciinormalizer',
		),
	),
),
'post_excerpt'          => array(
	'type' => 'text',
	'analyzer' => 'ik_max_word',
),
'post_password'         => array(
	'type' => 'text',
),
'post_content'          => array(
	'type' => 'text',
	'analyzer' => 'ik_max_word',
),
完整内容见本文末。 ElasticPress 文档链接:
  • https://github.com/10up/ElasticPress
  • https://www.elasticpress.io/resources/articles/
  • https://10up.github.io/ElasticPress/index.html

辅助 WordPress 插件

VK Filter Search 插件

VK Filter Search 是一款与古腾堡块编辑器(Gutenberg Block Editor)兼容的过滤和搜索插件。 描述:该插件可轻松地在 WordPress 网站的任何位置添加搜索框。如果网站有自定义文章类型,还可以按自定义文章类型缩小搜索范围。访客能够通过筛选后的类别、标签、自定义文章类型、关键字等搜索文章。
基本使用方法
激活 VK Filter Search 插件后,仪表盘(后台)会新增一个文章类型 “VK Filter Search”,该文章类型用于创建搜索表单。
此外,区块列表中还会新增以下三个区块:
  • VK Filter Search:用于创建搜索表单的区块。
  • 调用筛选搜索表单(Call Filter Search Form):用于调用在该文章类型中已注册的搜索表单的区块。
  • 搜索结果表单(Search Result Form):在区块主题(Block Theme)中,用于在搜索结果页面显示搜索表单的区块。
说明:“搜索结果表单” 区块仅适用于区块主题(Block Themes),在经典主题(Classic Themes)中无需使用。
搜索表单的注册与显示
如果启用了经典编辑器插件,需要禁用以启用区块编辑器(「古腾堡」)。
  • 注册搜索表单
    1. 步骤 1:在仪表盘的 “VK Filter Search” 菜单下,点击 “添加新项(Add New)”。
    2. 步骤 2:添加 “VK Filter Search” 区块并创建搜索表单。
    3. 步骤 3:插入预设区块
      在推荐列表中选择 “VK Filter Search Pro”,编辑区域会自动插入多个预设的筛选搜索区块,包括:
      • 分类法搜索专业版区块(设置为分类,Taxonomy Search Pro Block (Set to Category))
      • 分类法搜索专业版区块(设置为标签,Taxonomy Search Pro Block (Set to Tag))
      • 关键词搜索专业版区块(Keyword Search Pro Block)
      • 搜索按钮区块(Search Button Block)
    4. 步骤 4:自定义搜索表单设置
      选中 “VK Filter Search Pro” 区块,在右侧的 “区块设置” 中配置表单基本信息,可设置以下四项内容:
      • 文章类型目标(Target of Post Type):通过下拉菜单设置需要筛选的文章类型,如普通文章(post)、固定页面(fixed page)、自定义文章类型等。
      • 在搜索结果页面显示此表单(Display this form on search result page):开启(ON)后,搜索结果页面会显示该表单。
      • 在文章类型归档页显示(Display on post type archive):勾选对应的文章类型后,该文章类型的归档页顶部会显示搜索表单。
      • 提交按钮设置(Submit Button Settings):可编辑表单提交按钮的文本内容和样式。
        (操作选项:保存草稿(Save draft)、预览(Preview)、发布(Publish))
    5. 步骤 5:自定义内部区块布局
      内部区块可自由添加、删除和重新排序,操作选项包括:
      • 添加区块(Add block)
      • 删除区块(Remove block)
      • 移动区块(Move block)
        (操作选项:转为草稿(Switch to draft)、预览(Preview)、更新(Update))
    6. 步骤 6:自定义每个内部区块的设置
      可修改各区块的具体设置(如目标分类法、区块顺序等)。插件提供以下六个实用的内部区块:
      • VK 关键词搜索(VK Keyword Search)
      • VK 分类法搜索(VK Taxonomy Search)
      • VK 文章类型搜索(VK Post Type Search)
      • VK 文章日期搜索【专业版专属(Pro Only)】(VK Post Date Search)
      • 搜索结果单条排序【专业版专属(Pro Only)】(Search Result Single Order)
      • VK 自定义字段搜索(测试版)【专业版专属(Pro Only)】(VK Custom Field Search (Beta))
      此外,每个内部区块还可通过多种选项轻松自定义,包括:
      • 复选框(Checkbox)/ 单选按钮(Radio button)
      • 复选框选择的 “与(AND)/ 或(OR)” 搜索设置
      • 各屏幕尺寸下的区块宽度设置
      • 标签(项目名称)/ 占位符(placeholder)的文本可编辑
      • 搜索按钮的文本和样式可编辑
    7. 步骤 7:发布搜索表单
      点击 “保存草稿(Save draft)” 或 “发布(Publish)” 完成操作。
      (发布相关信息:可见性(Visibility)设为 “公开(Public)”,发布时间设为 “立即发布(Publish Immediately)”,作者(AUTHOR)为管理员(admin),可操作 “移至回收站(Move to trash)”,支持设置特色图片(Featured image))
  • 调用已注册的搜索表单
    1. 步骤 1:插入 “调用筛选搜索表单” 区块
      在需要显示搜索表单的页面中,插入 “调用筛选搜索表单(Call Filter Search Form)” 区块。
      (操作选项:保存草稿(Save draft)、发布(Publish))
    2. 步骤 2:指定已注册的搜索表单
      在右侧的设置边栏中,选择并指定已注册的搜索表单。
      (操作提示:选中该区块后,从设置边栏的 “选择筛选搜索表单(SELECT FILTER SEARCH FORM)” 下拉菜单中选择目标表单,默认显示 “未指定(Unspecified)”)
      (操作选项:保存草稿(Save draft)、发布(Publish))
    3. 步骤 3:发布页面
      完成设置后发布该页面。
    4. 步骤 4:检查搜索表单的显示效果
      访问已发布的页面(如 “设置搜索表单的页面(Page to set up the search form)”),确认搜索表单(含分类(Category)、关键词(Keyword)输入框及搜索(Search)按钮)是否正常显示。
    5. 步骤 5:【仅适用于全站点编辑(FSE)区块主题】([for FSE Block Theme only])
      如需在模板中添加 “搜索结果表单(Search Result Form)”,可按以下操作进行:
      该功能仅支持兼容全站点编辑(FSE)的区块主题,如需配置需额外操作,请根据红色提示信息完成设置。
此时,重新启用经典编辑器插件,编辑显示搜索表单的页面。即可看到 “调用筛选搜索表单(Call Filter Search Form)” 区块的代码:
<!-- wp:vk-filter-search/call-filter-search {"TargetPost":345024} /-->
在“小工具”,添加“区块”小工具到侧边栏,然后在其中填入上面的代码,即可在侧边栏中显示搜索表单。

Highlight Search Terms 插件

该插件用于在搜索结果页高亮显示搜索关键词,核心功能包括:
  • 点击穿透高亮:不仅在 WordPress 搜索结果页高亮字词,点击进入任一搜索结果文章页后,字词仍会保持高亮。
  • 字符与大小写不敏感:搜索匹配时忽略字符格式和大小写差异(如 “WordPress” 与 “wordpress” 均能被识别)。
  • 多平台兼容:支持 BuddyPress/bbPress 论坛搜索结果的字词高亮。
  • 缓存兼容:可与 WP Super Cache 等缓存插件协同工作,不影响高亮效果。
  • 精确匹配支持:用双引号包裹的搜索词会被视为单个完整术语(如 “wordpress plugin” 仅匹配完整短语,而非单独的 “wordpress” 或 “plugin”)。
现代 HTML5 浏览器会默认使用黄色背景(类似荧光笔)。插件无预设 CSS 样式,若需手动定义 CSS 规则,可在 WordPress 主题的 “自定义 CSS” 标签中添加规则。

4. 工作原理

插件会在搜索结果页的每篇文章中查找所有搜索字词,并用 <mark class="hilite term-N"> ... </mark> 标签包裹以实现高亮:
  • 其中 N 为数字,首个搜索词标记为 term-0,后续依次递增(如第二个词为 term-1)。
  • 用双引号包裹的搜索短语会被当作单个术语,对应一个 term-N 类。

使用 UFW 防火墙(Ubuntu)限制访问 Elasticsearch

注意 UFW 启用时,默认为 Default: deny (incoming), allow (outgoing), disabled (routed),UFW 不会主动断开已建立的连接,但新的连接请求会被拦截,因此,需立即允许 SSH 入站连接。
  • 查看并启用 UFW 防火墙 bash
    # 查看 UFW 防火墙状态
    sudo ufw status
    # 启用 UFW 防火墙
    sudo ufw enable
    # 允许 22 端口(SSH)的入站连接
    sudo ufw allow 22
  • 允许 WordPress 服务器访问 Elasticsearch 的端口9200:
    # 允许 192.168.1.0/24 网段访问 Elasticsearch 的 9200 端口
    sudo ufw allow from 192.168.1.0/24 to any port 9200。
    # 允许 192.168.1.100 这个 IP 地址访问 Elasticsearch 的 9200 端口
    sudo ufw allow from 192.168.1.100 to any port 9200。
    
  • 查看防火墙状态及已配置的规则,确认规则已正确添加:
    # 查看所有防火墙规则(简洁格式)
    sudo ufw status
    # 查看详细规则(包括端口、协议、来源等信息)
    sudo ufw status verbose
    # 查看编号形式的规则(便于后续删除或修改)
    sudo ufw status numbered

五、测试与维护

功能测试

  • 在 WordPress 前台搜索框输入关键词,验证结果:
    • 结果是否包含标题 / 内容匹配的文章;
    • 排序是否符合权重设置(标题匹配优先);
    • 响应速度是否比默认搜索(MariaDB)更快(可通过浏览器 F12 查看网络耗时)。

日常维护

  • 定期同步:若自动同步失效(如插件故障),需手动执行 “完整同步”;
  • 索引备份:若需备份 Elasticsearch 索引执行: bash
    # 备份名为 "examplecom-post-1" 的索引到 /backup 目录
    curl -k -u elastic:password -X POST "https://[Elasticsearch服务器IP]:9200/examplecom-post-1/_export?format=json" -o "~/backup/examplecom-post-1-backup.json"
    

附:

/var/www/example.com/wp-content/plugins/elasticpress/includes/mappings/post/7-0.php

<?php
/**
 * Elasticsearch mapping for ES 5.2
 *
 * @since  2.4
 * @package elasticpress
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

return array(
	'settings' => array(
		/**
		 * Filter number of Elasticsearch shards to use in indices
		 *
		 * @hook ep_default_index_number_of_shards
		 * @param  {int} $shards Number of shards
		 * @return {int} New number
		 */
		'index.number_of_shards'           => apply_filters( 'ep_default_index_number_of_shards', 5 ),
		/**
		 * Filter number of Elasticsearch replicas to use in indices
		 *
		 * @hook ep_default_index_number_of_replicas
		 * @param  {int} $replicas Number of replicas
		 * @return {int} New number
		 */
		'index.number_of_replicas'         => apply_filters( 'ep_default_index_number_of_replicas', 1 ),
		/**
		 * Filter Elasticsearch total field limit for posts
		 *
		 * @hook ep_total_field_limit
		 * @param  {int} $number Number of fields
		 * @return {int} New number
		 */
		'index.mapping.total_fields.limit' => apply_filters( 'ep_total_field_limit', 5000 ),
		/**
		 * Filter whether Elasticsearch ignores malformed fields or not.
		 *
		 * @hook ep_ignore_malformed
		 * @param  {bool} $ignore True for ignore
		 * @return {bool} New value
		 */
		'index.mapping.ignore_malformed'   => apply_filters( 'ep_ignore_malformed', true ),
		/**
		 * Filter Elasticsearch max result window for posts
		 *
		 * @hook ep_max_result_window
		 * @param  {int} $number Size of result window
		 * @return {int} New number
		 */
		'index.max_result_window'          => apply_filters( 'ep_max_result_window', 1000000 ),
		/**
		 * Filter Elasticsearch maximum shingle difference
		 *
		 * @hook ep_max_shingle_diff
		 * @param  {int} $number Max difference
		 * @return {int} New number
		 */
		'index.max_shingle_diff'           => apply_filters( 'ep_max_shingle_diff', 8 ),
		'analysis'                         => array(
			'analyzer'   => array(
				'default'          => array(
					'tokenizer'   => 'standard',
					/**
					 * Filter Elasticsearch default analyzer's filters
					 *
					 * @since 3.6.2
					 * @hook ep_default_analyzer_filters
					 * @param  {array<string>} $filters Default filters
					 * @return {array<string>} New filters
					 */
					'filter'      => apply_filters( 'ep_default_analyzer_filters', array( 'lowercase', 'ep_stop', 'ewp_snowball' ) ),
					/**
					 * Filter Elasticsearch default analyzer's char_filter
					 *
					 * @since 4.2.2
					 * @hook ep_default_analyzer_char_filters
					 * @param  {array<string>} $char_filters Default filter
					 * @return {array<string>} New filters
					 */
					'char_filter' => apply_filters( 'ep_default_analyzer_char_filters', array( 'html_strip' ) ),
					/**
					 * Filter Elasticsearch default language in mapping
					 *
					 * @hook ep_analyzer_language
					 * @param  {string} $lang Default language
					 * @param {string} $lang_context Language context
					 * @return {string} New language
					 */
					'language'    => apply_filters( 'ep_analyzer_language', 'english', 'analyzer_default' ),
				),
				'default_search'   => array(
					'tokenizer'   => 'standard',
					/**
					 * Filter Elasticsearch default analyzer's filters
					 *
					 * @since 5.0.0
					 * @hook ep_default_search_analyzer_filters
					 * @param  {array<string>} $filters Default filters
					 * @return {array<string>} New filters
					 */
					'filter'      => apply_filters( 'ep_default_search_analyzer_filters', array( 'lowercase', 'ep_stop', 'ewp_snowball' ) ),
					/**
					 * Filter Elasticsearch default analyzer's char_filter
					 *
					 * @since 5.0.0
					 * @hook ep_default_search_analyzer_char_filters
					 * @param  {array<string>} $char_filters Default filter
					 * @return {array<string>} New filters
					 */
					'char_filter' => apply_filters( 'ep_default_search_analyzer_char_filters', array( 'html_strip' ) ),
					/* This filter is documented above */
					'language'    => apply_filters( 'ep_analyzer_language', 'english', 'analyzer_default' ),
				),
				'shingle_analyzer' => array(
					'type'      => 'custom',
					'tokenizer' => 'standard',
					'filter'    => array( 'lowercase', 'shingle_filter' ),
				),
				'ewp_lowercase'    => array(
					'type'      => 'custom',
					'tokenizer' => 'keyword',
					'filter'    => array( 'lowercase' ),
				),
			),
			'filter'     => array(
				'shingle_filter' => array(
					'type'             => 'shingle',
					'min_shingle_size' => 2,
					'max_shingle_size' => 5,
				),
				'ewp_snowball'   => array(
					'type'     => 'snowball',
					/* This filter is documented in includes/mappings/post/7-0.php */
					'language' => apply_filters( 'ep_analyzer_language', 'english', 'filter_ewp_snowball' ),
				),
				'edge_ngram'     => array(
					'side'     => 'front',
					'max_gram' => 10,
					'min_gram' => 3,
					'type'     => 'edge_ngram',
				),
				'ep_stop'        => [
					'type'        => 'stop',
					'ignore_case' => true,
					/* This filter is documented in includes/mappings/post/7-0.php */
					'stopwords'   => apply_filters( 'ep_analyzer_language', 'english', 'filter_ep_stop' ),
				],
			),
			'normalizer' => array(
				'lowerasciinormalizer' => array(
					'type'   => 'custom',
					'filter' => array( 'lowercase', 'asciifolding' ),
				),
			),
		),
	),
	'mappings' => array(
		'_meta'             => array(
			'mapping_version' => '7-0.php',
		),
		'date_detection'    => false,
		'dynamic_templates' => array(
			array(
				'template_meta' => array(
					'path_match' => 'post_meta.*',
					'mapping'    => array(
						'type'   => 'text',
						'fields' => array(
							'{name}' => array(
								'type' => 'text',
							),
							'raw'    => array(
								'type'         => 'keyword',
								'ignore_above' => 10922,
							),
						),
					),
				),
			),
			array(
				'template_meta_types' => array(
					'path_match' => 'meta.*',
					'mapping'    => array(
						'type'       => 'object',
						'properties' => array(
							'value'    => array(
								'type'   => 'text',
								'fields' => array(
									'sortable' => array(
										'type'         => 'keyword',
										'ignore_above' => 10922,
										'normalizer'   => 'lowerasciinormalizer',
									),
									'raw'      => array(
										'type'         => 'keyword',
										'ignore_above' => 10922,
									),
								),
							),
							'raw'      => array( /* Left for backwards compat */
								'type'         => 'keyword',
								'ignore_above' => 10922,
							),
							'long'     => array(
								'type' => 'long',
							),
							'double'   => array(
								'type' => 'double',
							),
							'boolean'  => array(
								'type' => 'boolean',
							),
							'date'     => array(
								'type'   => 'date',
								'format' => 'yyyy-MM-dd',
							),
							'datetime' => array(
								'type'   => 'date',
								'format' => 'yyyy-MM-dd HH:mm:ss',
							),
							'time'     => array(
								'type'   => 'date',
								'format' => 'HH:mm:ss',
							),
						),
					),
				),
			),
			array(
				'template_terms' => array(
					'path_match' => 'terms.*',
					'mapping'    => array(
						'type'       => 'object',
						'properties' => array(
							'name'             => array(
								'type'   => 'text',
								'fields' => array(
									'raw'      => array(
										'type' => 'keyword',
									),
									'sortable' => array(
										'type'       => 'keyword',
										'normalizer' => 'lowerasciinormalizer',
									),
								),
							),
							'term_id'          => array(
								'type' => 'long',
							),
							'term_taxonomy_id' => array(
								'type' => 'long',
							),
							'parent'           => array(
								'type' => 'long',
							),
							'slug'             => array(
								'type' => 'keyword',
							),
							'facet'            => array(
								'type' => 'keyword',
							),
							'term_order'       => array(
								'type' => 'long',
							),
						),
					),
				),
			),
			array(
				'term_suggest' => array(
					'path_match' => 'term_suggest_*',
					'mapping'    => array(
						'type'     => 'completion',
						'analyzer' => 'default',
					),
				),
			),
		),
		'properties'        => array(
			'post_id'               => array(
				'type' => 'long',
			),
			'ID'                    => array(
				'type' => 'long',
			),
			'post_author'           => array(
				'type'       => 'object',
				'properties' => array(
					'display_name' => array(
						'type'   => 'text',
						'fields' => array(
							'raw'      => array(
								'type' => 'keyword',
							),
							'sortable' => array(
								'type'       => 'keyword',
								'normalizer' => 'lowerasciinormalizer',
							),
						),
					),
					'login'        => array(
						'type'   => 'text',
						'fields' => array(
							'raw'      => array(
								'type' => 'keyword',
							),
							'sortable' => array(
								'type'       => 'keyword',
								'normalizer' => 'lowerasciinormalizer',
							),
						),
					),
					'id'           => array(
						'type' => 'long',
					),
					'raw'          => array(
						'type' => 'keyword',
					),
				),
			),
			'post_date'             => array(
				'type'   => 'date',
				'format' => 'yyyy-MM-dd HH:mm:ss',
			),
			'post_date_gmt'         => array(
				'type'   => 'date',
				'format' => 'yyyy-MM-dd HH:mm:ss',
			),
			'post_title'            => array(
				'type'   => 'text',
				'fields' => array(
					'post_title' => array(
						'type'     => 'text',
						'analyzer' => 'ik_max_word',
					),
					'raw'        => array(
						'type'         => 'keyword',
						'ignore_above' => 10922,
					),
					'sortable'   => array(
						'type'         => 'keyword',
						'ignore_above' => 10922,
						'normalizer'   => 'lowerasciinormalizer',
					),
				),
			),
			'post_excerpt'          => array(
				'type' => 'text',
				'analyzer' => 'ik_max_word',
			),
			'post_password'         => array(
				'type' => 'text',
			),
			'post_content'          => array(
				'type' => 'text',
				'analyzer' => 'ik_max_word',

			),
			'post_content_filtered' => array(
				'type' => 'text',
			),
			'post_status'           => array(
				'type' => 'keyword',
			),
			'post_name'             => array(
				'type'   => 'text',
				'fields' => array(
					'post_name' => array(
						'type' => 'text',
					),
					'raw'       => array(
						'type'         => 'keyword',
						'ignore_above' => 10922,
					),
				),
			),
			'post_modified'         => array(
				'type'   => 'date',
				'format' => 'yyyy-MM-dd HH:mm:ss',
			),
			'post_modified_gmt'     => array(
				'type'   => 'date',
				'format' => 'yyyy-MM-dd HH:mm:ss',
			),
			'post_parent'           => array(
				'type' => 'long',
			),
			'post_type'             => array(
				'type'   => 'text',
				'fields' => array(
					'post_type' => array(
						'type' => 'text',
					),
					'raw'       => array(
						'type' => 'keyword',
					),
				),
			),
			'post_mime_type'        => array(
				'type' => 'keyword',
			),
			'permalink'             => array(
				'type' => 'keyword',
			),
			'guid'                  => array(
				'type' => 'keyword',
			),
			'terms'                 => array(
				'type' => 'object',
			),
			'post_meta'             => array(
				'type' => 'object',
			),
			'meta'                  => array(
				'type' => 'object',
			),
			'date_terms'            => array(
				'type'       => 'object',
				'properties' => array(
					'year'          => array( // 4 digit year (e.g. 2011).
						'type' => 'integer',
					),
					'month'         => array( // Month number (from 1 to 12) alternate name 'monthnum'.
						'type' => 'integer',
					),
					'm'             => array( // YearMonth (For e.g.: 201307).
						'type' => 'integer',
					),
					'week'          => array( // Week of the year (from 0 to 53) alternate name 'w'.
						'type' => 'integer',
					),
					'day'           => array( // Day of the month (from 1 to 31).
						'type' => 'integer',
					),
					'dayofweek'     => array( // Accepts numbers 1-7 (1 is Sunday).
						'type' => 'integer',
					),
					'dayofweek_iso' => array( // Accepts numbers 1-7 (1 is Monday).
						'type' => 'integer',
					),
					'dayofyear'     => array( // Accepts numbers 1-366.
						'type' => 'integer',
					),
					'hour'          => array( // Hour (from 0 to 23).
						'type' => 'integer',
					),
					'minute'        => array( // Minute (from 0 to 59).
						'type' => 'integer',
					),
					'second'        => array( // Second (0 to 59).
						'type' => 'integer',
					),
				),
			),
			'thumbnail'             => array(
				'type'       => 'object',
				'properties' => array(
					'ID'     => array(
						'type' => 'long',
					),
					'src'    => array(
						'type' => 'text',
					),
					'width'  => array(
						'type' => 'integer',
					),
					'height' => array(
						'type' => 'integer',
					),
					'alt'    => array(
						'type' => 'text',
					),
				),
			),
		),
	),
);

类别

  • 文章

Archives

©2015-2025 艾丽卡 support@alaica.com