devgeniem/redipress

RediPress

安装次数: 25,973

依赖关系: 0

建议者: 0

安全性: 0

星标: 33

关注者: 28

分支: 5

公开问题: 39

类型:wordpress-plugin

2.0.11 2024-09-06 05:04 UTC

This package is auto-updated.

Last update: 2024-09-24 13:09:06 UTC


README

一个提供超快搜索引擎和WP查询性能增强的WordPress插件。

RediPress利用流行的内存键值数据库Redis及其RediSearch模块,该模块提供了一种非常高效的全文搜索引擎和Redis上的二级索引。

插件挂钩到各种WordPress API、钩子和过滤器,以在RediSearch中创建WordPress帖子数据库表的副本,并保持其最新状态。它还挂钩到WP_Query并将所有合适的查询重定向到RediSearch而不是MySQL,这使得查询速度大大提高,在很多情况下几乎是瞬时的。

RediPress还提供了一些原始WordPress搜索所缺少的高级搜索功能,例如带权重的搜索词和模糊搜索。

RediPress还构建了大量的钩子和过滤器,以定制其功能以满足开发者的需求。除了优化查询之外,RediPress还通过包括非WordPress帖子在内的搜索结果或添加和查询索引中的位置数据的能力,带来了完全新的功能。

目录

要求

  • Redis + RediSearch模块。至少需要RediSearch的2.2.1版本。插件已测试至2.6.8版本。
  • WordPress版本5.9.0或更高版本。插件也可以与早期版本一起使用,但尚未进行测试。

安装和初始化

  1. 安装Redis并带有RediSearch,并确保可以从WordPress安装中连接到它。
  2. 安装并激活RediPress插件。目前唯一的安装方法是Composer。
  3. 在管理面板中或在代码中作为常量定义连接参数(推荐)。
  4. 如果您计划将自定义帖子或附加字段包含在搜索索引中,应现在进行。
  5. 为RediSearch创建索引模式。这可以在管理面板中或通过WP-CLI使用命令wp redipress create posts来完成。
  6. 运行实际索引。这也可以在管理面板中或通过WP-CLI完成。运行命令wp redipress index posts是运行初始索引的建议方法。如果索引停止,可以通过运行命令wp redipress index posts missing来继续索引。

多站点安装的索引

您可以使用与单站点相同的命令:wp redipress create postswp redipress index posts。对于多站点,必须使用--url参数指定站点URL,以便RediPress能够正常工作。例如wp redipress index --url=subsite.domain.test

使用

RediPress 的基本用法通过 WP_Query 类来实现。您可以使用该类及其相关函数(如 get_posts()),就像平时一样,RediPress 会将其钩子插入查询,并在 RediSearch 数据库上运行它们,而不是常规的 MySQL,从而实现更低的延迟和查询时间。

与一些其他类似加速查询的插件不同,您不需要向查询中添加任何参数,因为 RediPress 了解其能力,并自动处理所有查询。如果遇到无法处理的查询,它会自动回退到 MySQL。

额外参数

除了常规参数外,还有一些额外的参数可以使用。

地理位置

如果您为索引定义了地理位置字段,可以使用 WP_Query 轻松查询它们。查询应放在 WP_Query 参数数组的根级别,如下所示

'geolocation'    => [
    'field'    => 'location',
    'compare'  => '<',
    'lat'      => 59.6,
    'lng'      => 16.5,
    'distance' => 100000,
],
  • field 是您在索引中定义的字段名称。
  • compare<>,取决于您想要的结果是靠近还是远离参考点。
  • latlng 是用于计算距离的参考点的坐标。
  • distance 是从参考点到进行比较的值的距离,单位为
排序

如果您想根据到某些坐标的距离对 WP_Query 结果进行排序,可以通过定义如下所示的 WP_Query orderby 参数来实现

'orderby' => [
    [
        'orderby' => 'location',
        'order'   => 'ASC',
        'compare' => [
            'lat' => 59.6,
            'lng' => 16.5,
        ]
    ]
]

这将根据给定的坐标对查询结果进行排序。

权重

如果未在搜索查询中设置排序参数或 orderby 设置为 relevance,RediPress 使用 RediSearch 的默认相关性计算来对结果进行排序。默认情况下,它将 post_title 字段以分数 5.0 评分,post_excerpt2.0 评分,其他字段以 1.0 评分。这些都可以通过过滤器进行更改。

在查询时,还可以为某些值指定自定义权重。

帖子类型

可以在管理面板或代码中为不同的文章类型指定自定义权重。在代码中,这是通过向 WP_Query 参数中添加具有 post_type 作为键的自定义 weight 参数并传递一个包含文章类型及其权重的键值对数组来完成的。

new WP_Query([
    'post_type' => 'any',
    'orderby'   => 'relevance',
    'weight'    => [
        'post_type' => [
            'post'             => 1.5,
            'page'             => 3.0,
            'custom_post_type' => 7.0,
        ],
    ],
]);
作者

您还可以为不同的文章作者指定不同的权重。到目前为止,还没有管理功能来实现这一点,必须在代码中完成。

new WP_Query([
    'post_type' => 'any',
    'orderby'   => 'relevance',
    'weight'    => [
        'author' => [
            'admin'      => 1.5,
            'jane_doe'   => 2.0,
            'john_smith' => 5.0,
        ],
    ],
]);
分类术语

还可以根据具有特定分类术语的文章比其他文章更高。在这种情况下,taxonomy 参数中的第一级是分类名称,其值是另一个关联数组,包含术语及其权重的键值对。

new WP_Query([
    'post_type' => 'any',
    'orderby'   => 'relevance',
    'weight'    => [
        'taxonomy' => [
            'category' => [
                'news'          => 3.0,
                'announcements' => 5.0,
            ],
            'post_tag' => [
                'some_tag'    => 4.25,
                'another_tag' => 6.0,
            ],
        ],
    ],
]);
元值

也可以为元值定义权重。显然,元键应该添加到 RediPress 索引中,并设置为 queryable。在这种情况下,meta 中的第一级是元键,其值是另一个关联数组,包含值及其权重的键值对。

new WP_Query([
    'post_type' => 'any',
    'orderby'   => 'relevance',
    'weight'    => [
        'meta' => [
            'meta_key1' => [
                'foo' => 2.0,
                'bar' => 3.0,
            ],
            'another_key' => [
                'fizz' => 1.25,
                'buzz' => 3.0,
            ],
        ],
    ],
]);

模糊匹配

RediPress 支持 s 参数的搜索词模糊匹配。Levenshtein 距离的设置可以是 123。此设置也可以在管理面板中设置。

new WP_Query([
    's'         => 'foobar',
    'post_type' => 'any',
    'fuzzy'     => 2,
]);

多站点搜索

RediPress 支持使用特殊的 blog 查询参数通过一个查询从多个站点进行搜索。在一个数组中设置站点 ID 以指定应针对哪些站点。您可以使用字符串 'all' 来搜索所有站点,或者省略该值以仅搜索当前站点(默认)。

new WP_Query([
    's'         => 'foobar',
    'post_type' => 'any',
    'blog'      => [ get_main_site_id(), 2, 3 ],
]);

默认情况下,RediPress 不在结果对象中包含博客 ID,但您可以使用 redipress/return_fields 过滤器将其添加。

add_filter(
    'redipress/return_fields',
    function ( $return_fields ) {
        $return_fields[] = 'blog_id';

        return $return_fields;
    }
);

之后,您可以使用blog_id,例如在redipress/formatted_search_results过滤器中。

add_filter(
    'redipress/formatted_search_results',
    function ( $results, $raw_results ) {

        // Format the raw results into associative array.
        $formatted_raw_results = array_map( function ( $result ) {
            return \Geniem\RediPress\Utility::format( $result );
        }, $raw_results );

        foreach ( $results as $key => $result ) {
            $raw             = $formatted_raw_results[ $key ] ?? [];
            $result->blog_id = (int) $raw['blog_id'] ?? 0;
        }

        return $results;
    },
    10,
    2,
);

过滤器

查询部分

要自定义RediSearch查询,您可以使用以下过滤器过滤单个查询部分:

  • redipress/sortby
  • redipress/applies
  • redipress/filters
  • redipress/groupby
  • redipress/reduce_functions
  • redipress/load

扩展

RediPress旨在尽可能开发者友好。几乎所有内容都可以进行过滤,并且有很多动作可以与之交互。

添加自定义字段

要将自定义字段添加到RediPress索引中,必须完成两件事:在表模式中注册一个新的字段,并在索引和保存帖子时为该字段提供数据的过滤器中添加一个。

添加新的模式字段通过redipress/index/posts/schema_fields过滤器实现。(与redipress/index/users/schema_fields过滤器类似)它过滤一个扩展Geniem\RediPress\Entity\SchemaField的对象数组。目前选项包括数字字段、文本字段和标签字段。这些字段之间的区别可以从官方RediSearch文档中读取。

add_filter( 'redipress/index/posts/schema_fields', function( $fields ) {
    $fields[] = new \Geniem\RediPress\Entity\TextField([
        'name'     => 'my_field_name',
        'weight'   => 1.5,
        'sortable' => true,
    ]);

    return $fields;
}, 10, 1 );

注意 如果创建了新字段,则需要重新创建索引。这可以通过wp redipress drop posts命令实现,与1.x版本不同,该命令不会清空索引,而是仅删除模式,然后可以使用create命令重新创建。

当自定义字段创建并放入模式中后,下一步是提供一个函数来填充字段的值。这通过redipress/additional_field/{field_name}过滤器实现。该过滤器在每次索引帖子时都会被调用,无论它是保存帖子操作、完全重新索引,还是通过例如WP-CLI命令。

add_filter( 'redipress/additional_field/my_field_name', function( $data, $post_id, $post ) {
    return get_post_meta( $post_id, 'my_field_name', true );
}, 10, 1 );

修改帖子对象

RediPress在索引中存储序列化的帖子对象。在保存之前可以修改它,这允许开发者存储要使用的数据以供以后检索。

这通过redipress/post_object过滤器实现。在下面的示例中,包括了帖子的所有ACF字段。

add_filter( 'redipress/post_object', function( $post ) {
    $post->fields = \get_fields( $post->ID );

    return $post;
}, 10, 1 );

第三方插件

高级自定义字段

ACF Codifier中有很多功能用于与RediPress交互。如果没有Codifier,ACF字段应通过过滤器包含在索引中。

Polylang

RediPress默认支持Polylang。其他多语言插件可能需要一些编程才能工作。

故障排除

如果您遇到问题,可以尝试运行wp redipress drop posts来删除所有索引。您还可以通过添加--delete-data标志来删除所有帖子。之后重新索引。

WP-CLI

命令:wp redipress delete

描述:根据参数从索引中删除帖子。参数

  • document field: 任何应匹配给定值的文档字段。
  • limit: 如果未定义,则默认值为100。

示例用法

wp redipress delete --blog_id=1 --post_type=article --limit=500