open-csp / wiki-search

Semantic MediaWiki的分面搜索

安装数: 1,378

依赖项: 0

建议者: 0

安全: 0

星级: 5

关注者: 2

分支: 4

开放问题: 4

类型:mediawiki-extension

v8.0.1 2024-07-25 09:31 UTC

README

本文件描述了如何使用WikiSearch API。要了解WikiSearch的更入门级的介绍,您应该阅读MediaWiki扩展页面上的文档。

执行搜索

执行搜索并返回搜索结果列表。如果API处于调试模式,此端点还将返回执行搜索所使用的原始ElasticSearch查询。

参数

示例请求

示例请求(cURL)

curl https://wiki.example.org/api.php \
-d action=query \
-d format=json \
-d meta=WikiSearch \
-d filter=[{"value":"5","key":"Average rating","range":{"gte":5,"lte":6}}] \
-d from=0 \
-d limit=10 \
-d pageid=698 \
-d aggregations=[
    {"type":"range","ranges":[
        {"from":1,"to":6,"key":"1"},
        {"from":2,"to":6,"key":"2"},
        {"from":3,"to":6,"key":"3"},
        {"from":4,"to":6,"key":"4"},
        {"from":5,"to":6,"key":"5"}
    ],"property":"Average rating"}
]

示例响应

{
    "batchcomplete": "",
    "result": {
        "hits": "[<TRUNCATED, SEE BELOW FOR PARSING>]",
        "total": 1,
        "aggs": {
            "Average rating": {
                "meta": [],
                "doc_count": 1,
                "Average rating": {
                    "buckets": {
                        "1": {
                            "from": 1,
                            "to": 6,
                            "doc_count": 1
                        },
                        "2": {
                            "from": 2,
                            "to": 6,
                            "doc_count": 1
                        },
                        "3": {
                            "from": 3,
                            "to": 6,
                            "doc_count": 1
                        },
                        "4": {
                            "from": 4,
                            "to": 6,
                            "doc_count": 1
                        },
                        "5": {
                            "from": 5,
                            "to": 6,
                            "doc_count": 1
                        }
                    }
                }
            }
        }
    }
}

解析响应

本节假设您已成功使用PHP向API发出请求,并将原始API结果存储在变量$response中。

$response对象是一个JSON编码的字符串,在使用之前需要解码。

$response = json_decode($response, true);

解码$response对象后,响应通常包含两个键(如果启用调试模式,则为三个键)

通常,我们只对API结果对象感兴趣,因此我们可以创建一个只包含该字段的变量

$result = $response["result"];

$result字段将类似于以下内容

{
    "hits": "[<TRUNCATED, SEE BELOW FOR PARSING>]",
    "total": 1,
    "aggs": {
        "Average rating": {
            "meta": [],
            "doc_count": 1,
            "Average rating": {
                "buckets": {
                    "1": {
                        "from": 1,
                        "to": 6,
                        "doc_count": 1
                    },
                    "2": {
                        "from": 2,
                        "to": 6,
                        "doc_count": 1
                    },
                    "3": {
                        "from": 3,
                        "to": 6,
                        "doc_count": 1
                    },
                    "4": {
                        "from": 4,
                        "to": 6,
                        "doc_count": 1
                    },
                    "5": {
                        "from": 5,
                        "to": 6,
                        "doc_count": 1
                    }
                }
            }
        }
    }
}

《hits》字段

《hits》字段包含ElasticSearch搜索结果的JSON编码字符串。在使用之前,需要使用json_decode对其进行解码。该字段直接对应于ElasticSearch响应中的hits.hits字段。有关此字段外观的详细信息,请参阅ElasticSearch文档

要获取任何搜索结果的关联页面名称,可以将《hits》字段中的《subject.namespacename》和《subject.title》hit-field使用冒号连接起来,如下所示

$hits = json_decode($result["hits"], true);

foreach ($hits as $hit) {
    $namespace_name = $hit["subject"]["namespacename"];
    $page_title = $hit["subject"]["title"];

    $page_name = sprintf("%s:%s", $namespace_name, $page_title);

    echo $page_name;
}

《subject.namespacename》hit-field包含搜索结果所在的命名空间名称,而《subject.title》hit-field包含匹配搜索的页面名称(没有命名空间前缀)。要获取此页面的完整URL,可以在页面名称前添加http://<wikiurl>/index.php/

《hits》字段还包含可用的生成的突出显示片段。可以通过highlight hit-field访问它们,如下所示

$hits = json_decode($result["hits"], true);

foreach ($hits as $hit) {
    $highlights = $hit["highlight"];
    
    foreach ($highlights as $highlight) {
        // $highlight is an array of highlighted snippets

        $highlight_string = implode("", $highlight);
    
        echo $highlight_string;
    }
}

请参阅ElasticSearch突出显示文档

《aggs》字段

《aggs》字段直接对应于ElasticSearch响应中的《aggregations》字段。有关更多详细信息,请参阅ElasticSearch文档

《total》字段

《total》字段包含ElasticSearch找到的结果总数。该字段不受limit的影响,始终显示可用的总结果数,而不管实际返回了多少。

过滤器语法

filter参数接受一个对象列表。这些对象具有以下形式

PropertyRangeFilter

此过滤器仅返回具有指定属性且具有指定范围内值的页面。

{
    "key": "Age",
    "range": {
        "gte": 0,
        "lt": 100
    }
}

上述过滤器仅包括属性Age的值大于或等于0,但严格小于100的页面。

range参数接受一个对象,该对象允许以下属性

  • gte:大于或等于
  • gt:严格大于
  • lte:小于或等于
  • lt:严格小于

PropertyValueFilter

此过滤器仅返回具有指定属性和值的页面。

{
    "key": "Class",
    "value": "Manual"
}

上述过滤器仅包括属性Class的值为Manual的页面。该value可以是以下数据类型中的任何一种

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • 双精度浮点数

另请参阅:https://elastic.ac.cn/guide/en/elasticsearch/reference/5.6/query-dsl-range-query.html

PropertyValuesFilter

此过滤器仅返回具有指定属性和任何指定值的页面。

{
    "key": "Class",
    "value": ["foo", "bar"]
}

上述过滤器仅包括属性Class的值为foobar的页面。

另请参阅:https://elastic.ac.cn/guide/en/elasticsearch/reference/6.8//query-dsl-terms-query.html

HasPropertyFilter

此过滤器仅返回具有指定属性和任何值的页面。

{
    "key": "Class",
    "value": "+"
}

上述过滤器仅包括具有属性Class的页面。它不考虑属性的值。

另请参阅:https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-exists-query.html

PropertyTextFilter

此过滤器仅返回具有与给定搜索查询字符串匹配的值的指定属性的页面。

{
    "key": "Class",
    "value": "Foo | (Bar + Quz)",
    "type": "query"
}

上述过滤器执行给定的查询,仅包括与执行查询匹配的页面。查询语法与ElasticSearch使用的简单查询语法相同。

另请参阅:https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html

PropertyFuzzyValueFilter

此过滤器仅返回具有大约指定值的指定属性的页面。

{
    "key": "Class",
    "value": "Manual",
    "type": "fuzzy"
}

上述过滤器仅包括属性Class的值类似于Manual的页面。该value必须是一个字符串。

此外,可以通过fuzziness参数指定最大编辑距离

{
    "key": "Class",
    "value": "Manual",
    "type": "fuzzy",
    "fuzziness": 6
}

fuzziness必须是字符串“AUTO”以自动确定适当的模糊度(默认),或是一个指定最大编辑距离的正整数。

另请参阅:https://elastic.ac.cn/guide/en/elasticsearch/reference/5.6/query-dsl-fuzzy-query.html

聚合语法

aggregations参数接受一个对象列表。这些对象具有以下形式

PropertyRangeAggregation

{
    "type": "range",
    "ranges": [
        { "to": 50 },
        { "from": 50, "to": 100 },
        { "from": 100 }
    ],
    "property": "Price",
    "name": "Prices" # Optional, property name when empty
}

注意:from参数是包含的,而to参数是不包含的。这意味着对于从(包括)1到(包括)5的聚合,fromto参数分别应该是16(!)。

另请参阅:https://elastic.ac.cn/guide/en/elasticsearch/reference/5.6/search-aggregations-bucket-range-aggregation.html

PropertyAggregation

{
    "type": "property",
    "property": "Genre",
    "name": "Genres" # Optional, property name when empty
}

另请参阅:https://elastic.ac.cn/guide/en/elasticsearch/reference/5.6/search-aggregations-bucket-terms-aggregation.html

排序语法

sortings参数接受一个对象列表。这些对象具有以下形式

PropertySort

{
    "type": "property",
    "property": "Genre",
    "order": "asc" # Optional, undefined when empty
}

上述过滤器根据属性Genre的值以升序对结果进行排序。也可以按降序排序。

注意:对不存在的属性进行排序会导致错误。

高亮API

注意:此API主要用于内部使用。

高亮API具有以下属性

  • query:用于生成高亮术语的查询
  • properties:需要计算高亮的属性
  • page_id:需要计算高亮的页面的页面ID
  • limit:要计算的术语数量;这不一定直接对应于返回的术语数量,因为查询ElasticSearch后已经删除了重复项
  • size:生成的摘录的(近似)大小,留空以高亮单个单词

链式属性

WikiSearch提供创建具有链式属性过滤器的支持。链式属性可以用于任何过滤器。它们还可以用作搜索术语属性。

{
    "key": "Subpage.Foobar",
    "value": "+"
}

例如,上述过滤器匹配任何“Subpage”属性的值是包含“Foobar”属性页面的页面。

另请参阅:https://www.semantic-mediawiki.org/wiki/Help:Subqueries_and_property_chains

特殊属性

有一些由Semantic MediaWiki定义的特殊属性值得指出。这些属性就像常规属性一样,但不会出现在Special:Browse中。

  • text_copy:(来自SemanticMediaWiki文档)此映射用于启用对文本注释元素的广泛邻近搜索。当不知道特定属性时,text_copy字段是所有要搜索的字符串的复合字段。
  • text_raw:此映射包含来自文章的非结构化、未经处理的原始文本。
  • attachment-title:此映射包含文件附件的标题。
  • attachment-content:此映射包含文件附件的内容。

例如,如果您想通过Pdf属性搜索链接的PDF文件,您可以使用链式属性Pdf.attachment-content

钩子

WikiSearchBeforeElasticQuery

此钩子在查询发送到ElasticSearch之前被调用。它具有以下签名

function onWikiSearchBeforeElasticQuery( array &$query, array &$hosts ) {}

钩子可以访问并修改给定的$query。它还可以向$hosts数组添加或删除主机。

WikiSearchApplyResultTranslations

此钩子在将最终结果返回给API之前被调用。它可以用来修改$results数组。这可以用来过滤用户无权查看的任何页面或向查询结果添加额外的数据。

它具有以下签名

function onWikiSearchApplyResultTranslations( array &$results ) {}

WikiSearchOnLoadFrontend

任何WikiSearch前端都必须实现此钩子。它会在调用#loadSeachEngine解析函数时被调用。它具有以下签名

function onWikiSearchOnLoadFrontend( 
    string &$result, 
    \WikiSearch\SearchEngineConfig $config, 
    Parser $parser, 
    array $parameters 
) {}
  • string &$result:解析函数调用的结果。这是将被内嵌到页面上的文本。
  • SearchEngineConfig $config:当前页面的SearchEngineConfig对象。SearchEngineConfig对象公开以下方法
    • getTitle(): Title:与SearchEngineConfig关联的Title
    • getConditionProperty(): PropertyInfo:与搜索条件中属性关联的PropertyInfo对象(例如,对于Class=Foobar中的Class
      • PropertyInfo类公开以下方法
        • getPropertyID(): int:返回属性ID
        • getPropertyType(): string:返回属性类型(例如,txtFieldwpgField
        • getPropertyName(): string:返回属性名称(例如,Class
    • getConditionValue(): string:返回条件中的值(例如,在Class=Foobar中的Foobar
    • getFacetProperties(): array:返回配置中的维面属性(维面属性是不以?为前缀的属性)。可能是属性的名称(例如,“Foobar”)或翻译对(例如,“Foobar=Boofar”)
    • getFacetPropertyIDs(): 数组:返回一个键值对列表,键是属性分面的ID,值是该属性的类型
    • getResultProperties(): 数组:以 PropertyInfo 对象的形式返回配置中的结果属性(结果属性是带有前缀 ? 的属性)
    • getResultPropertyIDs(): 数组:返回一个键值对列表,键是结果属性的名称,值是该属性的ID
    • getSearchParameters(): 数组:返回额外搜索参数的键值对列表
  • Parser $parser:当前解析器对象
  • 数组 $parameters:传递给 #loadSearchEngine 调用的参数

配置变量

WikiSearch 有几个配置变量会影响其默认行为。

  • $wgWikiSearchElasticStoreIndex:设置要使用的 ElasticStore 索引名称(默认为 "smw-data-" . strtolower( wfWikiID() )
  • $wgWikiSearchDefaultResultLimit:设置在没有给出显式限制时返回的结果数量(默认为 10
  • $wgWikiSearchHighlightFragmentSize:设置高亮片段的最大字符数(默认为 250
  • $wgWikiSearchHighlightNumberOfFragments:设置每个结果返回的高亮片段的最大数量(默认为 1
  • $wgWikiSearchElasticSearchHosts:设置要使用的 ElasticSearch 主机列表(默认为 ["localhost:9200"]
  • $wgWikiSearchAPIRequiredRights:设置查询 WikiSearch API 所需的权限列表(默认为 ["read", "wikisearch-execute-api"]
  • $wgWikiSearchSearchFieldOverride:设置使用 Special:Search 时重定向到的搜索页面。如果可用,用户将被重定向到指定的维基文章,并通过搜索页指定的查询参数 search_query 进行重定向。不会更改使用内联搜索字段时显示的搜索片段的行为。
  • $wgWikiSearchMaxChainedQuerySize:设置链式属性查询检索的最大结果数量(默认为 1000)。将此设置为极端值可能导致在执行大链查询时 ElasticSearch 空间不足。

调试模式

要启用调试模式,将 $wgWikiSearchEnableDebugMode 设置为 true

解析器函数

WikiSearch 定义了两个解析器函数。

#WikiSearchConfig(区分大小写)

用于设置安全原因不能传递给 API 的几个配置变量的 #WikiSearchConfig 解析器函数。它设置该页的搜索条件、属性分面的列表和结果属性的列表。

{{#WikiSearchConfig:
  |<facet property>
  |?<result property>
}}
{{#WikiSearchConfig:
  |Version
  |Tag
  |Space
  |?Title
  |?Version
}}

注意:每页只允许调用一次 #WikiSearchConfig。多次调用会导致行为不可预测。

搜索参数

某些配置参数也可以通过搜索引擎配置提供。本节将记录这些参数及其行为。

基本查询

可以使用 基本查询 配置参数向搜索添加基本查询。此基本查询以语义媒体Wiki查询的形式给出。只有当文档同时匹配基本查询和生成的查询时,才会将其包含在搜索中。

高亮属性

可以使用 高亮属性 配置参数指定应高亮显示的替代属性。请注意,这些属性必须是搜索空间的一部分。

搜索词属性

可以使用 搜索词属性 配置参数指定在执行自由文本搜索时通过其进行搜索的替代属性。这些属性也可以是链式属性。

可以使用 ^%d 语法为搜索词属性中的每个字段添加权重。例如,为了给标题添加额外的权重,可以进行以下操作:

|search term properties=Title^10,Content^2,Pdf.attachment-content

权重决定了排序时的排名。在相关性排序中,字段权重越高,匹配度对相关性分数的贡献越大。如果未指定权重,则权重默认设置为 1

默认操作符

可以使用 default operator 配置参数来更改全文搜索的默认操作符。默认情况下,在每个词之间插入的操作符是 or,该配置参数允许管理员在需要时将其更改为 and

后过滤属性

可以使用 post filter properties 配置参数来指定哪些过滤器应作为后过滤添加而不是常规过滤。该参数接受以逗号分隔的属性名列表。适用于任何给定属性名的每个过滤器都将作为后过滤添加。后过滤和常规过滤之间的区别请参阅此处。此配置参数在您有分离的复选框属性时特别有用。

#WikiSearchFrontend(区分大小写)

使用 #WikiSearchFrontend 解析函数来加载前端。该解析函数的参数和返回值完全取决于前端。

安装

  • 下载文件并将其放置在您的 extensions/ 文件夹中名为 WikiSearch 的目录中。
  • 在您的 LocalSettings.php 文件底部添加以下代码
    • wfLoadExtension( 'WikiSearch' );
  • 运行更新脚本,该脚本将自动创建此扩展所需的所有数据库表。
  • 运行 Composer。
  • 转到您的维基百科上的特殊:版本页面,以验证扩展是否成功安装。

版权

MediaWiki 的分面搜索。版权所有(C)2021- Marijn van Wezel,Robis Koopmans

本程序是免费软件;您可以在自由软件基金会的GNU通用公共许可证的条款和条件下重新分发和/或修改它;许可证的第2版,或者(根据您的选择)许可证的任何较新版本。

本程序是在希望它有用的希望下分发的;但没有任何保证;甚至没有关于适销性或针对特定目的的适用性的暗示保证。有关详细信息,请参阅GNU通用公共许可证。

您应该已随本程序收到GNU通用公共许可证的一份副本;如果没有,请写信给自由软件基金会,Inc.,51 Franklin Street,第五层,波士顿,MA 02110-1301,美国。