open-csp / wiki-search
Semantic MediaWiki的分面搜索
Requires
- php: >= 7.4 < 8.3
- composer/installers: 1.*,>=1.0.1
- elasticsearch/elasticsearch: ^5.3|^6.0|^7.12
- ongr/elasticsearch-dsl: ~6.0|^7.2
- paquettg/php-html-parser: >=3.0
Requires (Dev)
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; } }
《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
的值为foo
或bar
的页面。
另请参阅: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使用的简单查询语法相同。
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
的聚合,from
和to
参数分别应该是1
和6
(!)。
PropertyAggregation
{
"type": "property",
"property": "Genre",
"name": "Genres" # Optional, property name when empty
}
排序语法
sortings
参数接受一个对象列表。这些对象具有以下形式
PropertySort
{
"type": "property",
"property": "Genre",
"order": "asc" # Optional, undefined when empty
}
上述过滤器根据属性Genre
的值以升序对结果进行排序。也可以按降序排序。
注意:对不存在的属性进行排序会导致错误。
高亮API
注意:此API主要用于内部使用。
高亮API具有以下属性
query
:用于生成高亮术语的查询properties
:需要计算高亮的属性page_id
:需要计算高亮的页面的页面IDlimit
:要计算的术语数量;这不一定直接对应于返回的术语数量,因为查询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关联的TitlegetConditionProperty(): PropertyInfo
:与搜索条件中属性关联的PropertyInfo对象(例如,对于Class=Foobar
中的Class
)- PropertyInfo类公开以下方法
getPropertyID(): int
:返回属性IDgetPropertyType(): string
:返回属性类型(例如,txtField
或wpgField
)getPropertyName(): string
:返回属性名称(例如,Class
)
- PropertyInfo类公开以下方法
getConditionValue(): string
:返回条件中的值(例如,在Class=Foobar
中的Foobar
)getFacetProperties(): array
:返回配置中的维面属性(维面属性是不以?
为前缀的属性)。可能是属性的名称(例如,“Foobar”)或翻译对(例如,“Foobar=Boofar”)getFacetPropertyIDs(): 数组
:返回一个键值对列表,键是属性分面的ID,值是该属性的类型getResultProperties(): 数组
:以 PropertyInfo 对象的形式返回配置中的结果属性(结果属性是带有前缀?
的属性)getResultPropertyIDs(): 数组
:返回一个键值对列表,键是结果属性的名称,值是该属性的IDgetSearchParameters(): 数组
:返回额外搜索参数的键值对列表
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,美国。