扩展再研究¶
reresearch支持扩展机制,就像Redis支持模块一样。API目前是非常小的,它还不支持在运行时动态加载扩展。相反,扩展必须用C(或一种与C有接口的语言)编写,并编译成将在运行时加载的动态库。
目前有两种扩展API:
- 查询扩展器,其角色是展开查询令牌(即stemmers)。
- 评分函数,其角色是在查询时间内对搜索结果进行排序。
注册和加载扩展¶
扩展应该被编译到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);返回词频-逆向文件频率;}