跳到内容

扩展再研究

reresearch支持扩展机制,就像Redis支持模块一样。API目前是非常小的,它还不支持在运行时动态加载扩展。相反,扩展必须用C(或一种与C有接口的语言)编写,并编译成将在运行时加载的动态库。

目前有两种扩展API:

  1. 查询扩展器,其角色是展开查询令牌(即stemmers)。
  2. 评分函数,其角色是在查询时间内对搜索结果进行排序。

注册和加载扩展

扩展应该被编译到so文件中,并在模块初始化时加载到reresearch中。

  • 编译

    扩展应该作为动态库进行编译和链接。扩展的Makefile示例可以在这里找到.

    该文件夹还包含一个用于测试的示例扩展,可以作为实现您自己的扩展的框架。

  • 加载

    加载扩展是通过追加EXTLOAD{路径/ / ext.so}之后loadmodule当加载reresearchch时,配置指令。例如:

    sh$redis server--loadmodule./redSearch.so EXTLOAD./ext/my_extension.so

    这会导致RedSearch自动加载扩展并注册其扩展器和记分器。

初始化扩展

扩展的入口点是带有签名的函数:

intRS_扩展单元(RSExtensionCtx*ctx);

加载扩展时,RedSearch会查找并调用此函数。此函数负责注册和初始化扩展器和记分器。

错误时返回REDISEARCH_ERR,成功时返回REDISEARCH_OK。

init函数示例

#包括< redisearch.h >//必须在包含路径中intRS_扩展单元(RSExtensionCtx*ctx){/*使用别名my_scorer注册计分函数,无特殊的私有数据和自由函数*/如果(ctx->RegisterScoringFunction(“my_scorer”,MyCustomScorer,,)==REDISEARCH_ERR){返回REDISEARCH_ERR;}/*注册一个查询扩展器如果(ctx->注册表查询器(“我的扩展器”,迈斯潘,,)==REDISEARCH_ERR){返回REDISEARCH_ERR;}返回重新搜索好吗;}

调用自定义函数

执行查询时,您可以通过使用给定别名指定SCORER或EXPANDER参数,告知RedSearch使用您的SCORER或EXPANDER。例如:

FT.SEARCH my_index“foo bar”扩展器my_扩展器记分器my_记分器

请注意扩展器和记分器别名为区分大小写的.

查询扩展器API

目前,我们只支持基本的查询扩展,一次一个令牌。扩展器可以决定使用任意数量的令牌扩展任何给定的令牌,这些令牌将在查询时合并。

扩展器的API如下所示:

#包括< redisearch.h >//必须在包含路径中无效MyQueryExpander(RSQueryExpanderCtx*ctx,RSToken*令牌){...}

RSQueryExpanderCtx

RSQueryExpanderCtx是包含扩展的私有数据的上下文,是扩展查询的回调方法。它定义为:

类型定义结构RSQueryExpanderCtx{/*引擎内部使用的不透明查询对象,不应访问*/结构RSQuery*查询;/*引擎内部使用的不透明查询节点对象,不应访问*/结构RSQueryNode**当前节点;/*扩展的私有数据,在扩展初始化时设置*/无效*私密数据;/*查询的语言,默认为“英语”*/常数字符*语言;/*ExpandToken允许用户在查询中添加令牌的扩展,即*联合在查询时与给定标记合并。str是扩展字符串,len是其长度,*和标志是一个32位标志掩码,可以使用的扩展设置私人信息*代币*/无效(*ExpandToken)(结构RSQueryExpanderCtx*ctx,常数字符*str,size_t伦恩,RSTokenFlags旗帜);/*SetPayload允许查询扩展器在查询上设置全局负载(每个令牌不唯一)*/无效(*SetPayload)(结构RSQueryExpanderCtx*ctx,有效载荷有效载荷);}RSQueryExpanderCtx;

RSToken

RSToken表示要扩展的单个查询令牌,定义为:

/*查询中的标记。扩展器接收查询令牌,并可以使用更多查询扩展查询*代币*/类型定义结构{/*标记字符串——可能以NULL结尾,也可能不是常数字符*str;/* token长度*/size_t伦恩;/* 1如果令牌是查询展开的结果*/uint8\u t扩大:1.;/*可由评分函数稍后检查的特定于扩展的令牌标志*/RSTokenFlags旗帜;}RSToken;

评分函数API

评分函数接收查询所评估的每个文档,以进行最终排名。它可以访问生成文档的所有查询词,以及文档的元数据,例如其A-priory分数、长度等。

由于评分功能是评估每个文档,可能数百万次,由于redis是单线程-这是重要的,它的工作速度尽可能快,并大量优化。

评分函数应用于每个潜在结果(每个文档),并通过以下签名实现:

双重的MyScoringFunction(RSScoringFunctionCtx*ctx,RSIndexResult*物件,RSDocumentMetadata*dmd,双重的明斯克);

RSScoringFunctionCtx是一个上下文,它实现了一些帮助器方法。

RSIndexResult是结果信息—包含文档id、频率、术语和偏移量。

RSDocumentMetadata是一个保存文档全局信息的对象,比如它的a-priory分数。

minSocre是生成与搜索相关的结果的最低分数。它可以用于在我们开始之前中途停止处理。

函数的返回值是双精度的,表示结果的最终分数。返回0会对结果进行计数,但如果有得分大于0的结果,它们将显示在其上方。为了完全过滤出一个结果而不计入总数,记分员应该返回特殊值RS\u分数\u过滤器输出(内部设置为负无穷,或-1/0)。

RSScoringFunctionCtx

这是一个包含以下成员的对象:

  • void*私有数据:指向扩展在初始化时设置的对象的指针。
  • 有效载荷:由查询扩展器或客户端设置的Payload对象。
  • int GetSlop(RSIndexResult*res):一种回调方法,用于生成查询项之间的总最小距离。此方法可用于选择“slop”较小且项彼此较近的结果。

RSIndexResult

这是一个包含索引中当前结果信息的对象,它是导致当前文档被视为有效结果的所有术语的集合。

有关详细信息,请参见重新搜索.h

RSDocumentMetadata

这是一个描述全局信息的对象,与当前查询无关,该信息是关于被评分函数评估的文档的。

示例查询扩展器

这个示例查询扩展器用术语foo展开每个令牌:

#包括< redisearch.h >//必须在包含路径中无效DummyExpander(RSQueryExpanderCtx*ctx,RSToken*令牌){ctx->ExpandToken(ctx,标准(“foo”),斯特伦(“foo”),0x1337);}

示例得分函数

这是一个实际的评分函数,计算文档的TF-IDF,乘以文档分数,再除以斜率:

#包括< redisearch.h >//必须在包含路径中双重的记分员(RSScoringFunctionCtx*ctx,RSIndexResult*H,RSDocumentMetadata*dmd,双重的明斯克){//无需评估得分为0的文档如果(dmd->分数==0)返回0;//计算结果中每一项的sum(tf-idf)双重的词频-逆向文件频率=0;对于(int=0;<H->numRecords;++){//取术语频率乘以术语IDF,将其加到总数中词频-逆向文件频率+ =(浮动)H->记录[].频率*(H->记录[].学期?H->记录[].学期->以色列国防军:0);}//通过文档中任何术语的最大频率进行规范化词频-逆向文件频率/ =(双重的)dmd->maxFreq;//乘以文档分数(介于0和1之间)词频-逆向文件频率* =dmd->分数;//如果tfidf已经低于最小值,则不需要分解slop如果(词频-逆向文件频率<明斯克){返回0;}//获取slop并将结果除以它,确保我们更喜欢具有更接近项的结果词频-逆向文件频率/ =(双重的)ctx->GetSlop(H);返回词频-逆向文件频率;}
Baidu