├── README.md ├── blog └── 2. Introducing RediSearch 2.0.md └── redisearch ├── 1.Home.md ├── 10.ChineseSupport.md ├── 2.QuickStart.md ├── 3.CommandReference.md ├── 4.Configuration.md ├── 5.Development.md ├── 6.Clients.md ├── 7.Administration ├── 1.GeneralAdministration.md └── 2.UpgradeTo2.0WhenRunningInRedisOSS.md ├── 8.Reference ├── 1.QuerySyntax.md ├── 10.StemmingSupport.md ├── 11.SynonymsSupport.md ├── 12.DocumentPayload.md ├── 13.SpellingCorrection.md ├── 14.PhoneticMatching.md ├── 2.Stop-Words.md ├── 3.Aggregations.md ├── 4.Tokenization and Escaping.md ├── 5.Sortable Values.md ├── 6.Tag Fields.md ├── 7.Highlighting Results.md ├── 8.Scoring Documents.md └── 9.Extension API.md └── 9.DesignDocuments └── 1.GarbageCollection.md /README.md: -------------------------------------------------------------------------------- 1 | RediSearch[官方文档](https://oss.redislabs.com/redisearch/)翻译 2 | ========= 3 | 4 | 翻译RediSearch[官方文档](https://oss.redislabs.com/redisearch/)和[技术Blog](https://redislabs.com/blog/tech-blog/),搜狐视频基础架构组出品,如有问题,欢迎指出。 5 | 6 | 联系人: 7 | ---- 8 | 9 | - 张益军 10 | - 陈实 11 | - [吴文瑞](https://github.com/wwr) [曹茹](https://github.com/cassie-cao) 12 | 13 | 目录: 14 | ---- 15 | 16 | - [主页](redisearch/1.Home.md) 17 | - [快速开始](redisearch/2.QuickStart.md) 18 | - [命令参考](redisearch/3.CommandReference.md) 19 | - [配置](redisearch/4.Configuration.md) 20 | - [开发](redisearch/5.Development.md) 21 | - [客户端](redisearch/6.Clients.md) 22 | - [运维管理](redisearch/7.Administration) 23 | - [参考](redisearch/8.Reference) 24 | - [设计文档](redisearch/9.DesignDocuments) 25 | - [中文支持](redisearch/10.ChineseSupport.md) 26 | - [快速开始](redisearch/1.Home.md) 27 | - [技术博客](blog) 28 | -------------------------------------------------------------------------------- /blog/2. Introducing RediSearch 2.0.md: -------------------------------------------------------------------------------- 1 | # RediSearch 2.0介绍 2 | 3 | > RediSearch 2.0旨在改善开发者的体验,并且是RediSearch最具扩展性的版本。 另外:它比以前的版本快2.4倍。 4 | 5 | RediSearch是一个基于Redis的实时二级索引引擎,具有全文检索能力,是Redis最成熟的组件之一,并且在过去几个月,RediSearch的Docker镜像下载量增加了500%,RediSearch正变得越来越流行。RediSearch的流行也让用户将其用到更加广泛的场景,范围从[实时库存管理](https://redislabs.com/solutions/use-cases/real-time-inventory/)到[临时性检索](https://redislabs.com/blog/the-case-for-ephemeral-search/)。 6 | 7 | 为了扩大RediSearch的良好势头,RediSearch推出了2.0版本,该版本旨在改善开发人员的体验,并成为RediSearch最具扩展性的版本。RediSearch 2.0支持Redis Labs的[Active-Active地理分布技术](https://redislabs.com/redis-enterprise/technology/active-active-geo-distribution/),可扩展的同时不会出现宕机,并且加入[Redis对Flash的支持](https://redislabs.com/redis-enterprise/technology/redis-on-flash/)(当前仅是私有预览版)。为了在不对性能造成负面影响的前提下实现这些目标,RediSearch 2.0采用了全新的体系结构,并且达到了预想的目标,RediSearch 2.0比RediSearch 1.6快2.4倍。 8 | 9 | ## RediSearch 2.0全新架构揭秘 10 | 11 | 在Redis数据库中嵌入一个丰富的查询和聚合引擎,将使得Redis扩展到远超缓存的使用场景。通过RediSearch,你可以在需要使用复杂查询访问数据的情况下,将Redis用作首选数据库。更好的是,RediSearch保留了Redis世界一流的速度、可靠性和可伸缩性,并且不会增加创建和更新索引的代码复杂性。 12 | 13 | RediSearch 2.0重新设计了索引和数据同步的方式,现在不再需要通过索引写入数据(使用FT.ADD命令),而是跟踪以哈希写入的数据并对其进行同步索引。重新设计带来了API的一些更改,已经在之前的文章[RediSearch 2.0首个里程碑]( RediSearch 2.0 Hit Its First Milestone)有所讨论。 14 | ![](https://redislabs.com/wp-content/uploads/2020/09/redisearch-architecture-1-720x508.png) 15 | 16 | 新的架构带来两个主要好处。首先,现在更加容易在现有数据之上创建二级索引,你只需要将RediSearch添加到现有Redis数据库,创建索引,然后开始查询,不需要迁移数据或者使用新命令将数据添加到索引中。这极大地降低了RediSearch新用户的学习曲线,使你能够在现有Redis数据库上创建索引,甚至不需要重启。 17 | 18 | 除了采用新的方式索引数据之外,RediSearch 2.0还从键空间中移除了索引。这将启用Redis企业版的[Active-Active技术](https://redislabs.com/redis-enterprise/technology/active-active-geo-distribution/),该技术基于[无冲突复制数据类型(CRDTs)](https://redislabs.com/blog/diving-into-crdts/)。无冲突的合并两个倒排索引是困难的,但是Redis Labs已经有[经过验证的哈希表的CRDT实现](https://redislabs.com/videos/active-active-geo-distribution-redis-enterprise/)。因此,新架构的第二个好处是使得RediSearch 2.0有更强的扩展性。由于RediSearch 2.0追踪哈希表并且从键空间移除了索引,因此你能够在使用Active-Active技术的地理分布数据库上运行RediSearch。 19 | ![](https://redislabs.com/wp-content/uploads/2020/09/redisearch-active-active-1.png) 20 | 文档会以最终一致性的方式同步到集群中的所有数据库,在每个副本,RediSearch会追踪哈希表上的所有更新操作,这意味着所有索引也可以实现最终一致性。 21 | 22 | ## 开源Redis的OSS集群支持 23 | 24 | 我们不想将伸缩能力的增强仅限于Redis企业版用户,因此我们对开源Redis集群版本也增加了在多个分片上扩展单个索引的支持。之前,单个RediSearch索引及其文档,必须依附于单个分片。这意味着OSS Redis的数据集大小和吞吐量会受限于单个Redis进程的处理能力。Redis企业版提供了在集群中分发文档,在查询时聚合的能力。这种分发和聚合的能力,是由一个叫做“协调器”的组件提供的,该组件现在也在Redis源码开源协议框架下开源出来,实现了目前最具扩展性的RediSearch版本。 25 | 26 | ## 性能指标 27 | 28 | 为了评估RediSearch 2.0吞吐性能,我们使用公开的[NYC Taxi数据集](https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page)拓展全文检索的基准测试。这个数据集由于其丰富的数据类型(文本、标签、地理数据和数字)和数量庞大的文档,而被业内广泛使用。 29 | 30 | 这个数据集聚焦于写入性能,使用了纽约市黄色出租车的行程记录数据。这次基准测试采用了2015年1月的数据集,加载了超过1200万个平均大小500字节的文档。完整的基础测试说明,请参考[FTSB on GitHub](https://github.com/RediSearch/ftsb/blob/master/docs/nyc_taxis-benchmark/description.md)。 31 | 32 | 所有基准测试用例都运行在AWS实例上,通过我们的基准测试框架进行配置。这些测试是在具有15个分片的3节点群集上执行的,其中RediSearch企业版本为1.6和2.0。基准测试客户端和开启RediSearch功能的3个节点,在单独的c5.9xlarge实例上运行。 33 | 34 | 考虑到RediSearch 2.0能够追踪Redis中哈希的变化并自动索引他们,我们加入了FT.ADD和HSET命令的变体。为了使升级更简单,我们在RediSearch 2.0中将弃用的FT.ADD命令重新映射为HSET命令。下面两个图展示了RediSearch 1.6和RediSearch 2.0的总体导入速率和延迟,同时保留了亚毫秒级的延迟数据。 35 | 36 | ![](https://redislabs.com/wp-content/uploads/2020/09/redisearch-2.0-graph-1-768x479.png) 37 | 38 | ![](https://redislabs.com/wp-content/uploads/2020/09/redisearch-2.0-graph-2-768x493.png) 39 | 40 | ## RediSearch 2.0的下一步工作 41 | 42 | 综上所述,对所有Redis用户而言,RediSearch 2.0是目前发布的最快和最具扩展性的版本。除此之外,RediSearch 2.0新的架构改善了开发者在Redis中为现有数据创建索引的体验,无需将现有数据迁移到另外一个支持RediSearch的数据库。这个新的架构允许RediSearch追踪其他数据结构,例如流和字符串,并对其自动创建索引。在接下来的版本,RediSearch可以让你使用其他数据结构,例如[RedisJSON](https://redislabs.com/modules/redis-json/)中的嵌套数据结构。 43 | 44 | 我们计划持续增加新的特性,以进一步改善开发者的体验。接下来,期待一个新的命令,允许你对查询进行调优,更好的找出查询执行过程中的瓶颈。 45 | 46 | 准备好开始了吗?接下来查看Tug Grall的博客[RediSearch 2.0入门](https://redislabs.com/blog/getting-started-with-redisearch-2-0/)。然后按照[这篇教程](https://github.com/RediSearch/redisearch-getting-started)中的步骤进行操作,或者可以在[Redis Enterprise Cloud Essentials](https://redislabs.com/try-free/)免费创建一个数据库。(请注意,公开预览版的RediSearch 2.0在两个Redis Enterprise Cloud Essentials区域中可用:孟买和俄勒冈州) 47 | 48 |   49 |   50 | 51 | 作者:[Pieter Cailliau](https://redislabs.com/blog/author/pcailliau/) 52 | 53 | 原文链接:[https://redislabs.com/blog/introducing-redisearch-2-0/](https://redislabs.com/blog/introducing-redisearch-2-0/) 54 | -------------------------------------------------------------------------------- /redisearch/1.Home.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sohutv/redisearch-docs/254a235f8babaddb1c522e845ffcec870d273482/redisearch/1.Home.md -------------------------------------------------------------------------------- /redisearch/10.ChineseSupport.md: -------------------------------------------------------------------------------- 1 | # 中文支持 2 | 3 | RediSearch从0.99.0版本开始支持添加中文文档。 4 | 5 | 中文支持允许添加中文文档,并正确分词,而不再按照空格和标点分词。 6 | 7 | 由于分词方式的不同,为中文文档创建索引不同于大多数其他语言。大多数语言可以使用空格或特定分隔符来分词,但在中文并不行。 8 | 9 | 中文分词的实现,是通过扫描输入文本并按照字典或预定义的术语表,检查每个字符或字符序列,找出最可能的匹配(基于相邻的字符)。 10 | 11 | RediSearch为此使用了Friso这个中文词库。这不需要其他配置,对用户是透明的。 12 | 13 | ## 举例:在RediSearch中使用中文 14 | 15 | 伪代码: 16 | ``` 17 | FT.CREATE idx SCHEMA txt TEXT 18 | FT.ADD idx docCn 1.0 LANGUAGE chinese FIELDS txt "Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。[8]" 19 | FT.SEARCH idx "数据" LANGUAGE chinese HIGHLIGHT SUMMARIZE 20 | # Outputs: 21 | # 数据?... 数据进行写操作。由于完全实现了发布... 数据冗余很有帮助。[8... 22 | ``` 23 | 使用Python客户端: 24 | ``` 25 | # -*- coding: utf-8 -*- 26 | 27 | from redisearch.client import Client, Query 28 | from redisearch import TextField 29 | 30 | client = Client('idx') 31 | try: 32 | client.drop_index() 33 | except: 34 | pass 35 | 36 | client.create_index([TextField('txt')]) 37 | 38 | # Add a document 39 | client.add_document('docCn1', 40 | txt='Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。[8]', 41 | language='chinese') 42 | print client.search(Query('数据').summarize().highlight().language('chinese')).docs[0].txt 43 | ``` 44 | 输入如下: 45 | ``` 46 | 数据?... 数据进行写操作。由于完全实现了发布... 数据冗余很有帮助。[8... 47 | ``` 48 | 49 | ## 使用自定义字典 50 | 51 | 如果需要使用自定义的字典,可以在加载模块时配置。FRISOINI选项可以指定friso.ini文件的位置,friso.ini文件包含了字典文件路径和相关配置。 52 | 注意,不存在默认的friso.ini文件位置。RediSearch带有其自己的friso.ini和字典文件,它们在构建时被编译到模块二进制文件中。 53 | -------------------------------------------------------------------------------- /redisearch/2.QuickStart.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sohutv/redisearch-docs/254a235f8babaddb1c522e845ffcec870d273482/redisearch/2.QuickStart.md -------------------------------------------------------------------------------- /redisearch/3.CommandReference.md: -------------------------------------------------------------------------------- 1 | # RedisSearch全命令文档 2 | 3 | ## 创建 4 | ### FT.CREATE 5 | #### 格式 6 | 7 | FT.CREATE {index} 8 | [ON {structure}] 9 | [PREFIX {count} {prefix} [{prefix} ..] 10 | [FILTER {filter}] 11 | [LANGUAGE {default_lang}] 12 | [LANGUAGE_FIELD {lang_field}] 13 | [SCORE {default_score}] 14 | [SCORE_FIELD {score_field}] 15 | [PAYLOAD_FIELD {payload_field}] 16 | [MAXTEXTFIELDS] [TEMPORARY {seconds}] [NOOFFSETS] [NOHL] [NOFIELDS] [NOFREQS] [SKIPINITIALSCAN] 17 | [STOPWORDS {num} {stopword} ...] 18 | SCHEMA {field} [TEXT [NOSTEM] [WEIGHT {weight}] [PHONETIC {matcher}] | NUMERIC | GEO | TAG [SEPARATOR {sep}] ] [SORTABLE][NOINDEX] ... 19 | 20 | #### 描述 21 | 创建具有给定规范的索引。 22 | 23 | 关于字段数限制的说明 24 | > RediSearch 每个模式最多支持 1024 个字段,其中最多 128 个可以是 TEXT 字段。在 32 位构建中,最多 64 个字段可以是 TEXT 字段。请注意,您拥有的字段越多,您的索引就越大,因为每增加 8 个字段,每个索引记录需要一个额外的字节进行编码。 NOFIELDS 如果您不需要按文本字段过滤,您可以始终使用该 选项而不将字段信息编码到索引中,以节省空间。这仍将允许按数字和地理字段进行过滤。 25 | 26 | 在集群数据库中运行的注意事项 27 | > 当集群数据库中有多个索引时,您需要确保要索引的文档与索引位于同一个分片上。您可以通过用索引名称标记您的文档来实现这一点。 28 | sql HSET doc:1{idx} ... FT.CREATE idx ... PREFIX 1 doc: ... 29 | 在集群数据库中运行 RediSearch 时,可以使用 RSCoordinator 跨越分片的索引 。在这种情况下,上述情况不适用。 30 | 31 | #### 例子 32 | 创建一个索引来存储标题、发布日期和关键字以 blog:post: (例如, blog:post:1 )开头的博客文章哈希的类别 : 33 | 34 | FT.CREATE idx ON HASH PREFIX 1 blog:post: SCHEMA title TEXT SORTABLE published_at NUMERIC SORTABLE category TAG SORTABLE 35 | 在同一个索引中索引两个不同的哈希——一个包含作者数据,一个包含书籍: 36 | 37 | FT.CREATE author-books-idx ON HASH PREFIX 2 author:details: book:details: SCHEMA author_id TAG SORTABLE author_ids TAG title TEXT name TEXT 38 | 39 | >注意 40 | > 41 | > 在此示例中,作者数据的键使用键模式, author:details: 而书籍数据的键使用模式 book:details: 。 42 | 43 | 只索引名字以“G”开头的作者: 44 | 45 | FT.CREATE g-authors-idx ON HASH PREFIX 1 author:details FILTER 'startswith(@name, "G")' SCHEMA name TEXT 46 | 仅索引有副标题的书籍: 47 | 48 | FT.CREATE subtitled-books-idx ON HASH PREFIX 1 book:details FILTER '@subtitle != ""' SCHEMA title TEXT 49 | 索引具有“类别”字段的书籍,其中用分号分隔值: 50 | 51 | FT.CREATE books-idx ON HASH PREFIX 1 book:details FILTER SCHEMA title TEXT categories TAG SEPARATOR ";" 52 | 53 | #### 参数 54 | - index : 要创建的索引名称。如果存在,则旧规范将被覆盖 55 | - ON {structure} 目前仅支持 HASH(默认) 56 | - PREFIX {count} {prefix} 告诉索引它应该索引哪些键。您可以为 index.html 添加多个前缀。由于参数是可选的,默认为 *(所有键) 57 | - FILTER {filter} 是一个具有完整 RediSearch 聚合表达式语言的过滤器表达式。可以使用@__key 访问刚刚添加/更改的密钥。一个字段可以通过传递来设置字段名 'FILTER @indexName=="myindexname"' 58 | - LANGUAGE {default_lang} :如果设置表示索引中文档的默认语言。默认为英文。 59 | - LANGUAGE_FIELD {lang_field} :如果设置表示应该用作文档语言的文档字段。 60 | 61 | >支持的语言 62 | > 63 | >在索引期间对提供的语言使用词干分析器。如果发送了不受支持的语言,该命令将返回错误。支持的语言有: 64 | >阿拉伯语、巴斯克语、加泰罗尼亚语、丹麦语、荷兰语、英语、芬兰语、法语、德语、希腊语、匈牙利语、印度尼西亚语、爱尔兰语、意大利语、立陶宛语、尼泊尔语、挪威语、葡萄牙语、罗马尼亚语、俄语、西班牙语、瑞典语、泰米尔语、土耳其语、中文。 65 | > 66 | >添加中文文档时, LANGUAGE chinese 应设置以便索引器正确标记术语。如果使用默认语言,则将根据标点符号和空格提取搜索词。中文分词器使用分段算法(通过 Friso ),该算法 对文本进行分段并对照预定义的字典进行检查。有关 更多信息,请参阅 词干 。 67 | 68 | - SCORE {default_score} :如果设置表示索引中文档的默认分数。默认分数为 1.0。 69 | - SCORE_FIELD {score_field} :如果设置,则表示应根据用户的排名用作文档排名的文档字段。排名必须介于 0.0 和 1.0 之间。如果未设置,则默认分数为 1。 70 | - PAYLOAD_FIELD {payload_field} :如果设置表示应该用作文档的二进制安全有效负载字符串的文档字段,可以在查询时由自定义评分函数评估,或检索到客户端。 71 | - MAXTEXTFIELDS :为了提高效率,如果创建的文本字段少于 32 个,RediSearch 会对索引进行不同的编码。此选项强制 RediSearch 将索引编码为超过 32 个文本字段,这允许您使用 FT.ALTER . 72 | - NOOFFSETS :如果设置,我们不存储文档的术语偏移量(节省内存,不允许精确搜索或突出显示)。暗示 NOHL 。 73 | - TEMPORARY :创建一个轻量级临时索引,该索引将在指定的不活动时间后过期。每当搜索或添加索引时,都会重置内部空闲计时器。由于此类索引是轻量级的,您可以创建数千个此类索引而不会对性能产生负面影响,因此您应该考虑使用它 SKIPINITIALSCAN 来避免昂贵的扫描。 74 | 75 | >关于删除临时索引的注意事项 76 | >删除时,临时索引不会删除散列,因为它们可能已在多个索引中编入索引。添加 DD 标志也会删除哈希。 77 | 78 | - NOHL :通过禁用突出显示支持来节省存储空间和内存。如果设置,我们不存储术语位置的相应字节偏移量。 NOHL 也由 暗示 NOOFFSETS 。 79 | - NOFIELDS :如果设置,我们不会为每个术语存储字段位。节省内存,不允许按特定字段过滤。 80 | - NOFREQS :如果设置,我们将避免在索引中保存词频。这可以节省内存,但不允许根据文档中给定术语的频率进行排序。 81 | - STOPWORDS :如果设置,我们使用自定义停用词列表设置索引,在索引和搜索期间将被忽略。{num} 是停用词的数量, 82 | + 跟一个长度正好为 {num} 的停用词参数列表。 83 | + 如果未设置,我们采用默认的停用词列表。 84 | + 如果 {num} 设置为 0,索引将没有停用词。 85 | 86 | - SKIPINITIALSCAN :如果设置,我们不扫描和索引。 87 | - SCHEMA {field name} {field type} {options...} :在 SCHEMA 关键字之后,我们定义索引字段。字段名称是此索引所遵循的散列中的字段名称。字段类型可以是数字、文本或地理。 88 | 89 | #### 字段类型 90 | - 文本 91 | 允许针对此字段中的值进行全文搜索查询。 92 | 93 | - 标签 94 | 允许针对此字段中的值进行精确匹配查询,例如类别或主键。有关更多信息,请参阅 标记字段 。 95 | 96 | - 数字 97 | 允许针对此字段中的值进行数字范围查询。有关 如何使用数字范围的详细信息,请参阅 查询语法文档 。 98 | 99 | - 地理位置 100 | 允许针对此字段中的值进行地理范围查询。该字段的值必须是一个字符串,其中包含以逗号分隔的经度(第一个)和纬度。 101 | 102 | #### 字段选项 103 | - SORTABLE 104 | 105 | 数字、标签或文本字段可以有可选的 SORTABLE 参数,允许用户稍后 根据该字段的值对结果进行排序 (这会增加内存开销,因此不要在大文本字段上声明它)。 106 | 107 | - NOSTEM 108 | 109 | 文本字段可以有 NOSTEM 参数,这将在索引其值时禁用词干。这对于诸如专有名词之类的东西可能是理想的。 110 | 111 | - NOINDEX 112 | 113 | 字段可以有 NOINDEX 选项,这意味着它们不会被索引。这与 SORTABLE ,结合使用非常有用 ,可以创建使用 PARTIAL 更新不会导致文档完全重新索引的字段。如果一个字段有 NOINDEX 而没有 SORTABLE,它就会被索引忽略。 114 | 115 | - PHONETIC {matcher} 116 | 117 | PHONETIC 默认情况下 ,将文本字段声明为 将在搜索中对其执行语音匹配。强制性 {matcher} 参数指定使用的语音算法和语言。支持以下匹配器: 118 | 119 | dm:en - 英语双元音 120 | dm:fr - 法语双元音 121 | dm:pt - 葡萄牙语双元音 122 | dm:es - 西班牙语双元音 123 | 有关更多详细信息,请参阅 语音匹配 。 124 | 125 | - WEIGHT {weight} 126 | 127 | 对于 TEXT 字段,在计算结果精度时声明该字段的重要性。这是一个乘法因子,如果未指定,则默认为 1。 128 | 129 | - SEPARATOR {sep} 130 | 131 | 对于 TAG 字段,指示如何将字段中包含的文本拆分为单独的标签。默认值为 , . 该值必须是单个字符。 132 | 133 | ### 复杂度 134 | O(1) 135 | 136 | ### 返回值 137 | OK或error 138 | 139 | ## 插入 140 | ### HSET/HSETNX/HDEL/HINCRBY/HDECRBY 141 | #### 格式 142 | 143 | HSET {hash} {field} {value} [{field} {value} ...] 144 | #### 描述 145 | 由于RediSearch V2.0,天然Redis命令用于添加,使用更新或删除散列 HSET , HINCRBY , HDEL 或改变散列其他散列命令。 146 | 147 | 如果修改了哈希,则所有匹配的索引都会自动更新。通过 redis 删除散列,无论是通过调用 DEL 、使散列过期还是逐出,也会自动处理。 148 | 149 | 如果一个字段没有被索引(例如,如果一个数字字段得到一个字符串值),整个文档就不会被索引。 FT.INFO 在 下提供文档索引失败的数量 hash_indexing_failures 。 150 | 151 | 如果 LANGUAGE_FIELD 、 SCORE_FIELD 或 PAYLOAD_FIELD 与 一起使用 FT.CREATE ,文档将提取属性。字段可用于获取其所属索引的名称。 152 | 153 | >架构不匹配 154 | > 155 | >如果哈希中的值与该字段的模式类型不匹配,则哈希索引将失败。“失败”文件的数量下 hash_indexing_failures 的 FT.INFO 。 156 | 157 | 158 | >可能修改索引的 redis 命令的完整列表: 159 | > 160 | >HSET、HMSET、HSETNX、HINCRBY、HINCRBYFLOAT、HDEL、DEL、SET、RENAME_FROM、RENAME_TO、TRIMMED、RESTORE、EXPIRED、EVICTED、CHANGE、LOADED 161 | 162 | #### 例子 163 | 164 | HSET doc1 cs101 "hello world" number 3.141 geopoint "-122.064228,37.377658" tags foo,bar,baz 165 | HSET doc2 cs201 "foo bar baz" number 2.718 geopoint "-0.084324,51.515583" tags foo,bar,baz 166 | HSET doc3 Name "RedisLabs" indexName "myindexname" 167 | 168 | >注意 169 | > 170 | >地理值的语法是带引号的字符串,经度(第一个)和纬度用逗号分隔。 171 | 172 | ## 检索 173 | ### FT.SEARCH 174 | #### 格式 175 | 176 | FT.SEARCH {index} {query} [NOCONTENT] [VERBATIM] [NOSTOPWORDS] [WITHSCORES] [WITHPAYLOADS] [WITHSORTKEYS] 177 | [FILTER {numeric_field} {min} {max}] ... 178 | [GEOFILTER {geo_field} {lon} {lat} {radius} m|km|mi|ft] 179 | [INKEYS {num} {key} ... ] 180 | [INFIELDS {num} {field} ... ] 181 | [RETURN {num} {field} ... ] 182 | [SUMMARIZE [FIELDS {num} {field} ... ] [FRAGS {num}] [LEN {fragsize}] [SEPARATOR {separator}]] 183 | [HIGHLIGHT [FIELDS {num} {field} ... ] [TAGS {open} {close}]] 184 | [SLOP {slop}] [INORDER] 185 | [LANGUAGE {language}] 186 | [EXPANDER {expander}] 187 | [SCORER {scorer}] [EXPLAINSCORE] 188 | [PAYLOAD {payload}] 189 | [SORTBY {field} [ASC|DESC]] 190 | [LIMIT offset num] 191 | ### 描述 192 | 使用文本查询搜索索引,返回文档或仅返回 id。 193 | 194 | #### 例子 195 | 在包含书籍数据的索引的每个 TEXT 字段中搜索术语“wizard”: 196 | 197 | FT.SEARCH books-idx "wizard" 198 | 仅在“标题”字段中搜索术语“狗”: 199 | 200 | FT.SEARCH books-idx "@title:dogs" 201 | 搜索 2020 年或 2021 年出版的书籍: 202 | 203 | 204 | FT.SEARCH books-idx "@published_at:[2020 2021] 205 | 搜索经度-122.41,纬度37.77(旧金山)5公里内的中餐馆: 206 | 207 | 208 | FT.SEARCH restaurants-idx "chinese @location:[-122.41 37.77 5 km]" 209 | 在“标题”字段中搜索术语“狗”或“猫”,但为“狗”的匹配项提供更高的相关性分数(也称为 boosting ): 210 | 211 | 212 | FT.SEARCH books-idx "(@title:dogs | @title:cats) | (@title:dogs) => { $weight: 5.0; }" 213 | 在索引的任何 TEXT 字段中搜索带有“dogs”的书籍,并要求对每个结果的评分进行解释: 214 | 215 | 216 | FT.SEARCH books-idx "dogs" WITHSCORES EXPLAINSCORE 217 | 搜索在标签字段“类别”中有“科学”的标题中带有“空格”的书籍: 218 | 219 | 220 | FT.SEARCH books-idx "@title:space @categories:{science}" 221 | 在任何文本字段中搜索带有“Python”的书籍,从整个结果集中的第十一个结果开始返回十个结果(偏移参数从零开始),并且每个结果只返回“标题”字段: 222 | 223 | 224 | FT.SEARCH books-idx "python" LIMIT 10 10 RETURN 1 title 225 | >更多例子 226 | > 227 | >有关更多详细信息和查询示例,请参阅 查询语法 。 228 | 229 | #### 参数 230 | - index : 索引名称。索引必须首先使用 FT.CREATE . 231 | - query : 要搜索的文本查询。如果它不止一个单词,请将其放在引号中。 有关更多详细信息,请参阅 查询语法 。 232 | - NOCONTENT :如果它出现在查询之后,我们只返回文档 ID 而不是内容。如果 RediSearch 只是外部文档集合的索引,这很有用 233 | - VERBATIM :如果设置,我们不会尝试使用词干进行查询扩展,而是逐字搜索查询词。 234 | - NOSTOPWORDS :如果设置,我们不会从查询中过滤停用词。 235 | - WITHSCORES :如果设置,我们还返回每个文档的相对内部分数。这可用于合并来自多个实例的结果 236 | - WITHPAYLOADS :如果设置,我们检索可选的文档有效负载(参见 FT.ADD)。有效载荷遵循文档 ID,如果 237 | - WITHSCORES 已设置,则遵循分数。 238 | - WITHSORTKEYS :仅与 SORTBY 相关 。返回排序键的值,紧跟在 id 和 score 和/或有效负载(如果需要)之后。这通常不是用户需要的,并且存在用于分布式搜索协调目的。 239 | - FILTER numeric_field min max :如果设置,并且 numeric_field 在 FT.CREATE 中被定义为数字字段,我们会将结果限制为数值范围在 min 和 max 之间的那些。min 和 max 遵循 ZRANGE 语法,可以是 -inf 、 +inf 并 ( 用于独占范围。一个查询支持针对不同字段的多个数字过滤器。 240 | - GEOFILTER {geo_field} {lon} {lat} {radius} m|km|mi|ft :如果设置,我们将结果从 lon 和 lat 过滤到给定的半径。半径以数字和单位给出。有关 更多详细信息,请参阅 GEORADIUS 。 241 | - INKEYS {num} {field} ... :如果设置,我们将结果限制为列表中指定的一组给定键。第一个参数必须是列表的长度,并且大于零。不存在的键会被忽略——除非所有的键都不存在。 242 | - INFIELDS {num} {field} ... :如果设置,则将结果过滤为仅出现在文档特定字段中的结果,例如标题或 URL。num 是指定字段参数的数量 243 | - RETURN {num} {field} ... :使用此关键字来限制返回文档中的哪些字段。 num 是关键字后面的字段数。如果 num 是 0,它的作用就像 NOCONTENT 。 244 | - SUMMARIZE ... :使用此选项仅返回包含匹配文本的字段部分。有关 更多详细信息, 请参阅 突出显示 245 | - HIGHLIGHT ... :使用此选项来格式化匹配文本的出现。有关 更多详细信息, 请参阅 突出显示 246 | - SLOP {slop} :如果设置,我们允许最多 N 个介于短语之间的不匹配偏移量。(即精确短语的斜率是 0) 247 | - INORDER :如果设置,并且通常与 SLOP 结合使用,我们确保查询词在文档中以与查询中相同的顺序出现,而不管它们之间的偏移量如何。 248 | - LANGUAGE {language} :如果设置,我们在搜索查询扩展期间对提供的语言使用词干分析器。如果查询中文文档,应设置为 chinese ,以便正确标记查询词。默认为英语。如果发送了不受支持的语言,该命令将返回错误。有关语言列表,请参阅 FT.ADD。 249 | - EXPANDER {expander} :如果设置,我们将使用自定义查询扩展器而不是词干分析器。 请参阅扩展 。 250 | - SCORER {scorer} :如果设置,我们将使用用户定义的自定义评分函数。 请参阅扩展 。 251 | - EXPLAINSCORE :如果设置,将返回如何计算分数的文本描述。使用此选项需要 WITHSCORES 选项。 252 | - PAYLOAD {payload} :添加将暴露给自定义评分函数的任意二进制安全有效负载。 请参阅扩展 。 253 | - SORTBY {field} [ASC|DESC] :如果指定,则结果按此字段的值排序。这适用于文本和数字字段。 254 | - LIMIT first num :将结果限制为给定的偏移量和结果数量。请注意,偏移量是零索引的。默认值为 0 10,从第一个结果开始返回 10 个项目。 255 | 256 | >提示: 257 | > 258 | >LIMIT 0 0 可用于计算结果集中的文档数,而无需实际返回它们。 259 | 260 | #### 复杂度 261 | O(n) 用于单个单词查询。 n 是结果集中的结果数。查找所有具有特定术语的文档是 O(1),但是,需要扫描所有这些文档才能从 redis 哈希加载文档数据并返回它们。 262 | 263 | 更复杂的查询的时间复杂度各不相同,但通常与单词的数量、它们之间的交点数量以及结果集中的结果数量成正比。 264 | 265 | #### 返回值 266 | 数组回复, 其中第一个元素是结果总数,然后是成对的文档 id,以及一个嵌套的字段/值数组。 267 | 268 | 如果 给出了 NOCONTENT ,我们将返回一个数组,其中第一个元素是结果总数,其余成员是文档 ID。 269 | 270 | >搜索查询期间哈希值过期 271 | > 272 | >如果在查询过程开始后到达散列到期时间,则该散列将计入结果总数,但不会返回散列的名称和内容。 273 | 274 | ### FT.AGGATE 275 | #### 格式 276 | 277 | FT.AGGREGATE {index_name} 278 | {query_string} 279 | [VERBATIM] 280 | [LOAD {nargs} {property} ...] 281 | [GROUPBY {nargs} {property} ... 282 | REDUCE {func} {nargs} {arg} ... [AS {name:string}] 283 | ... 284 | ] ... 285 | [SORTBY {nargs} {property} [ASC|DESC] ... [MAX {num}]] 286 | [APPLY {expr} AS {alias}] ... 287 | [LIMIT {offset} {num}] ... 288 | [FILTER {expr}] ... 289 | #### 描述 290 | 对索引运行搜索查询,并对结果执行聚合转换,从中提取统计信息等。有关 更多详细信息,请参阅 有关聚合的完整文档 。 291 | 292 | #### 例子 293 | 查找页面“about.html”的访问量,按访问天数分组,统计访问次数,按天排序: 294 | 295 | FT.AGGREGATE idx "@url:\"about.html\"" 296 | APPLY "day(@timestamp)" AS day 297 | GROUPBY 2 @day @country 298 | REDUCE count 0 AS num_visits 299 | SORTBY 4 @day 300 | 查找一年内出版最多的书籍: 301 | 302 | FT.AGGREGATE books-idx * 303 | GROUPBY 1 @published_year 304 | REDUCE COUNT 0 AS num_published 305 | GROUPBY 0 306 | REDUCE MAX 1 @num_published AS max_books_published_per_year 307 | >减少所有结果 308 | > 309 | >最后一个例子使用了 GROUPBY 0 . 用于 GROUPBY 0 对 REDUCE 聚合管道最后一步的所有结果应用 函数——这适用于初始查询和后续 GROUPBY 操作。 310 | 311 | 搜索经度 -73.982254 和纬度 40.753181 10 公里内的图书馆,然后用它们的位置和这些坐标之间的距离来注释它们: 312 | 313 | FT.AGGREGATE libraries-idx "@location:[-73.982254 40.753181 10 km]" 314 | LOAD 1 @location 315 | APPLY "geodistance(@location, -73.982254, 40.753181)" 316 | 在这里,我们需要使用 LOAD 预加载 @location 字段,因为它是一个 GEO 字段。 317 | 318 | >更多例子 319 | > 320 | >有关聚合的更多详细信息和聚合查询的详细示例,请参阅 聚合 。 321 | 322 | #### 参数 323 | - index_name :执行查询的索引。 324 | - query_string :检索文档的基本过滤查询。它遵循 与 搜索查询完全相同的语法 ,包括过滤器、联合、非、可选等。 325 | - LOAD {nargs} {property} ... :从文档 HASH 对象加载文档字段。作为一般经验法则,应该避免这种情况。聚合所需的字段应存储为 SORTABLE ,它们可用于聚合管道且延迟非常低。LOAD 极大地损害了聚合查询的性能,因为每个处理过的记录都需要对 Redis 键执行等效的 HMGET,当在数百万个键上执行时,处理时间会非常长。 326 | - GROUPBY {nargs} {property} :根据一个或多个属性对管道中的结果进行分组。每个组应该至少有一个减速器(见下文),一个处理组条目的函数,要么对它们进行计数,要么执行多个聚合操作(见下文)。 327 | + REDUCE {func} {nargs} {arg} … [AS {name}] :使用归约函数将每组中的匹配结果归约为 单个记录。例如 COUNT 将计算组中的记录数。有关可用减速器的更多详细信息,请参阅下面的减速器部分。 328 | + 减速器可以使用 AS {name} 可选参数拥有自己的属性名称 。如果未给出名称,则生成的名称将是 reduce 函数和组属性的名称。例如,如果 property 未将名称指定给 COUNT_DISTINCT @foo ,则生成的名称将为 count_distinct(@foo) 。 329 | 330 | - SORTBY {nargs} {property} {ASC|DESC} [MAX {num}] :使用属性列表对管道进行排序直到 SORTBY 点。默认情况下,排序是升序的,但 可以为每个属性添加 ASC 或 DESC 。 nargs 是排序参数的个数,包括 ASC 和 DESC。例如: SORTBY 4 @foo ASC @bar DESC 。 331 | 332 | MAX 用于优化排序,仅对 n 大元素进行排序。虽然它没有连接到 LIMIT ,但您通常只需要 SORTBY … MAX 进行常见查询。 333 | 334 | - APPLY {expr} AS {name} :对一个或多个属性应用 1 对 1 转换,并将结果存储为管道中的新属性,或使用此转换替换任何属性。 expr 是一个表达式,可用于对数字属性执行算术运算,或可根据属性类型应用于属性的函数(见下文),或其任意组合。例如: APPLY "sqrt(@foo)/log(@bar) + 5" AS baz 将为管道中的每条记录动态评估此表达式,并将结果存储为名为 baz 的新属性,该属性可以被管道中的进一步 APPLY / SORTBY / GROUPBY / REDUCE 操作引用。 335 | 336 | - LIMIT {offset} {num} 。限制结果数量以仅返回 num 从索引开始的结果 offset (从零开始)。如上所述, SORTBY … MAX 如果您只想限制排序操作的输出,那么使用它会更有效率 。 337 | 338 | 然而,limit 可用于限制结果而不进行排序,或用于对由 确定的 n 大结果进行分页 SORTBY MAX 。例如,获取前 100 个结果中的 50-100 个结果最有效地表示为 SORTBY 1 @foo MAX 100 LIMIT 50 50 。从 SORTBY 中删除 MAX 将导致管道对 所有 记录进行排序 ,然后对结果 50-100 进行分页。 339 | 340 | - FILTER {expr} 。使用与每个结果中的值相关的谓词表达式过滤结果。它们在查询后应用并与管道的当前状态相关。 341 | 342 | #### 复杂度 343 | 非确定性。取决于执行的查询和聚合,但通常与返回的结果数量成线性关系。 344 | 345 | #### 返回值 346 | 阵列响应。每行都是一个数组,代表一个聚合结果。 347 | 348 | #### 示例输出 349 | 这里我们按用户(演员)计算 GitHub 事件,以产生最活跃的用户: 350 | 351 | 127.0.0.1:6379> FT.AGGREGATE gh "*" GROUPBY 1 @actor REDUCE COUNT 0 AS num SORTBY 2 @num DESC MAX 10 352 | 1) (integer) 284784 353 | 2) 1) "actor" 354 | 2) "lombiqbot" 355 | 3) "num" 356 | 4) "22197" 357 | 3) 1) "actor" 358 | 2) "codepipeline-test" 359 | 3) "num" 360 | 4) "17746" 361 | 4) 1) "actor" 362 | 2) "direwolf-github" 363 | 3) "num" 364 | 4) "10683" 365 | 5) 1) "actor" 366 | 2) "ogate" 367 | 3) "num" 368 | 4) "6449" 369 | 6) 1) "actor" 370 | 2) "openlocalizationtest" 371 | 3) "num" 372 | 4) "4759" 373 | 7) 1) "actor" 374 | 2) "digimatic" 375 | 3) "num" 376 | 4) "3809" 377 | 8) 1) "actor" 378 | 2) "gugod" 379 | 3) "num" 380 | 4) "3512" 381 | 9) 1) "actor" 382 | 2) "xdzou" 383 | 3) "num" 384 | 4) "3216" 385 | [10](10)) 1) "actor" 386 | 2) "opstest" 387 | 3) "num" 388 | 4) "2863" 389 | 11) 1) "actor" 390 | 2) "jikker" 391 | 3) "num" 392 | 4) "2794" 393 | (0.59s) 394 | 395 | ### FT.EXPLAIN 396 | #### 格式 397 | 398 | FT.EXPLAIN {index} {query} 399 | #### 描述 400 | 返回复杂查询的执行计划。 401 | 402 | 在返回的响应中, + 术语上的 a 表示词干。 403 | 404 | #### 例子 405 | 406 | $ redis-cli --raw 407 | 408 | 127.0.0.1:6379> FT.EXPLAIN rd "(foo bar)|(hello world) @date:[100 200]|@date:[500 +inf]" 409 | INTERSECT { 410 | UNION { 411 | INTERSECT { 412 | foo 413 | bar 414 | } 415 | INTERSECT { 416 | hello 417 | world 418 | } 419 | } 420 | UNION { 421 | NUMERIC {100.000000 <= x <= 200.000000} 422 | NUMERIC {500.000000 <= x <= inf} 423 | } 424 | } 425 | #### 参数 426 | - index : 索引名称。索引必须先用 FT.CREATE 创建 427 | - query : 查询字符串,就像发送到 FT.SEARCH 428 | 429 | #### 复杂度 430 | O(1) 431 | 432 | #### 返回值 433 | 字符串响应。一个表示执行计划的字符串(见上面的例子)。 434 | 435 | >提示 436 | >您应该使用 redis-cli --raw 来正确读取返回响应中的换行符。 437 | 438 | ### FT.EXPLAINCLI 439 | #### 格式 440 | 441 | FT.EXPLAINCLI {index} {query} 442 | #### 描述 443 | 返回复杂查询的执行计划,但不使用 redis-cli --raw . 444 | 445 | 在返回的响应中, + 术语上的 a 表示词干。 446 | 447 | #### 例子 448 | 449 | $ redis-cli 450 | 451 | 127.0.0.1:6379> FT.EXPLAINCLI rd "(foo bar)|(hello world) @date:[100 200]|@date:[500 +inf]" 452 | 1) INTERSECT { 453 | 2) UNION { 454 | 3) INTERSECT { 455 | 4) UNION { 456 | 5) foo 457 | 6) +foo(expanded) 458 | 7) } 459 | 8) UNION { 460 | 9) bar 461 | 10) +bar(expanded) 462 | 11) } 463 | 12) } 464 | 13) INTERSECT { 465 | 14) UNION { 466 | 15) hello 467 | 16) +hello(expanded) 468 | 17) } 469 | 18) UNION { 470 | 19) world 471 | 20) +world(expanded) 472 | 21) } 473 | 22) } 474 | 23) } 475 | 24) UNION { 476 | 25) NUMERIC {100.000000 <= @date <= 200.000000} 477 | 26) NUMERIC {500.000000 <= @date <= inf} 478 | 27) } 479 | 28) } 480 | 29) 481 | #### 参数 482 | - index : 索引名称。索引必须先用 FT.CREATE 创建 483 | - query : 查询字符串,就像发送到 FT.SEARCH 484 | 485 | #### 复杂度 486 | O(1) 487 | 488 | #### 返回值 489 | 字符串响应。一个表示执行计划的字符串(见上面的例子)。 490 | 491 | ### FT.PROFILE 492 | #### 格式 493 | 494 | FT.PROFILE {index} {[SEARCH, AGGREGATE]} [LIMITED] QUERY {query} 495 | #### 描述 496 | 执行 FT.SEARCH 或 FT.AGGREGATE 命令并收集性能信息。返回值有一个包含两个元素的数组: 497 | 498 | - 结果 - 来自 RediSearch 的正常回复,类似于游标。 499 | - 资料 -资料中 的详细信息是: 500 | + Total profile time - 查询的总运行时间 。 501 | + 解析时间 - 将查询和参数解析为执行计划的时间。 502 | + 管道创建时间 - 执行计划的创建时间,包括迭代器、结果处理器和化简器的创建。 503 | + 迭代器配置文件 - 索引迭代器信息,包括它们的类型、术语、计数和时间数据。倒排索引迭代器还具有它们包含的元素数量。 504 | + 结果处理器配置文件 - 带有类型、计数和时间数据的结果处理器链。 505 | 506 | #### 例子 507 | 508 | FT.PROFILE idx SEARCH QUERY "hello world" 509 | 510 | 511 | 1) 1) (integer) 1 512 | 2) "doc1" 513 | 3) 1) "t" 514 | 2) "hello world" 515 | 2) 1) 1) Total profile time 516 | 2) "0.47199999999999998" 517 | 2) 1) Parsing time 518 | 2) "0.218" 519 | 3) 1) Pipeline creation time 520 | 2) "0.032000000000000001" 521 | 4) 1) Iterators profile 522 | 2) 1) Type 523 | 2) INTERSECT 524 | 3) Time 525 | 4) "0.025000000000000001" 526 | 5) Counter 527 | 6) (integer) 1 528 | 7) Children iterators 529 | 8) 1) Type 530 | 2) TEXT 531 | 3) Term 532 | 4) hello 533 | 5) Time 534 | 6) "0.0070000000000000001" 535 | 7) Counter 536 | 8) (integer) 1 537 | 9) Size 538 | 10) (integer) 1 539 | 9) 1) Type 540 | 2) TEXT 541 | 3) Term 542 | 4) world 543 | 5) Time 544 | 6) "0.0030000000000000001" 545 | 7) Counter 546 | 8) (integer) 1 547 | 9) Size 548 | 10) (integer) 1 549 | 5) 1) Result processors profile 550 | 2) 1) Type 551 | 2) Index 552 | 3) Time 553 | 4) "0.036999999999999998" 554 | 5) Counter 555 | 6) (integer) 1 556 | 3) 1) Type 557 | 2) Scorer 558 | 3) Time 559 | 4) "0.025000000000000001" 560 | 5) Counter 561 | 6) (integer) 1 562 | 4) 1) Type 563 | 2) Sorter 564 | 3) Time 565 | 4) "0.013999999999999999" 566 | 5) Counter 567 | 6) (integer) 1 568 | 5) 1) Type 569 | 2) Loader 570 | 3) Time 571 | 4) "0.10299999999999999" 572 | 5) Counter 573 | 6) (integer) 1 574 | #### 参数 575 | - index : 索引名称。索引必须先用 FT.CREATE 创建 576 | - SEARCH,AGGREGATE : FT.SEARCH 和 FT.AGGREGATE 577 | - LIMITED : 删除 reader 迭代器的 细节 578 | - QUERY {query} : 查询字符串,就像发送到 FT.SEARCH 579 | #### 复杂度 580 | 非确定性。取决于执行的查询和聚合,但通常与返回的结果数量成线性关系。 581 | 582 | #### 返回值 583 | 阵列响应。 584 | 585 | >提示 586 | > 587 | >要减少输出的大小,请使用 NOCONTENT 或 LIMIT 0 0 减少结果回复或 LIMITED 不回复 reader iterators 内部内置联合的详细信息, 例如 fuzzy 或 prefix 。 588 | 589 | ## 更新 590 | ### FT.ALTER SCHEMA ADD 591 | #### 格式 592 | 593 | FT.ALTER {index} SCHEMA ADD {field} {options} ... 594 | ####描述 595 | 向索引添加一个新字段。 596 | 597 | 在索引和重新索引现有文档时,向索引添加字段将导致任何未来的文档更新使用新字段。 598 | 599 | >注意 600 | > 601 | >根据索引的创建方式,您可能会受到可添加到现有索引的附加文本字段数量的限制。如果当前索引包含的文本字段少于 32 个,则 SCHEMA ADD 最多只能添加 32 个总字段(这意味着索引将只能包含 32 个总文本字段)。如果您希望索引包含 32 个以上的字段,请使用 MAXTEXTFIELDS 选项创建它 。 602 | 603 | #### 例子 604 | 605 | FT.ALTER idx SCHEMA ADD id2 NUMERIC SORTABLE 606 | #### 参数 607 | - index : 索引名称。 608 | - field:字段名称。 609 | - options :字段选项 - FT.CREATE 有关更多信息,请参阅 。 610 | 611 | #### 复杂度 612 | O(1) 613 | 614 | #### 返回值 615 | OK或error。 616 | 617 | ## 删除 618 | ### FT.DROPINDEX 619 | #### 格式 620 | 621 | FT.DROPINDEX {index} [DD] 622 | #### 描述 623 | 删除索引。 624 | 625 | 默认情况下,FT.DROPINDEX 不会删除与索引关联的文档哈希。添加 DD 选项也会删除哈希。 626 | 627 | 从 RediSearch 2.0 开始 628 | 629 | #### 例子 630 | 631 | FT.DROPINDEX idx DD 632 | #### 参数 633 | - index :全文索引名称。索引必须先用 FT.CREATE 创建 634 | - DD :如果设置,删除操作将删除实际的文档哈希。 635 | #### 返回值 636 | 状态回复:成功就返回OK。 637 | 638 | >注意: 639 | > 640 | >当使用带有参数 DD 的 FT.DROPINDEX 时,如果索引创建仍在运行(FT.CREATE 正在异步运行),则只会删除已被索引的文档哈希。留给索引的文档散列将保留在数据库中。您可以使用 FT.INFO 来检查索引的完成情况。 641 | 642 | ## 别名 643 | ### FT.ALIASADD 644 | ### FT.ALIASUPDATE 645 | ### FT.Aliasdel 646 | #### 格式 647 | 648 | FT.ALIASADD {name} {index} 649 | FT.ALIASUPDATE {name} {index} 650 | FT.ALIASDEL {name} 651 | 的 FT.ALIASADD 和 FT.ALIASDEL 命令将添加或从索引中删除别名。索引别名可用于引用数据命令中的实际索引,例如 FT.SEARCH 或 FT.ADD 。这允许管理员透明地将应用程序查询重定向到替代索引。 652 | 653 | 索引可以有多个别名,但别名不能引用另一个别名。 654 | 655 | 该 FT.ALIASUPDATE 命令与该 命令的不同之处在于 FT.ALIASADD 它将删除与先前索引的别名关联(如果有)。 FT.ALIASADD 另一方面,如果别名已经与另一个索引相关联,则会失败。 656 | 657 | #### 复杂度 658 | O(1) 659 | 660 | #### 返回值 661 | OK或error。 662 | 663 | ## 标签 664 | ### FT.TAGVALS 665 | #### 格式 666 | 667 | FT.TAGVALS {index} {field_name} 668 | #### 描述 669 | 返回在 Tag 字段中 索引的不同标签 。 670 | 671 | 如果您的标签字段索引诸如城市、类别等内容,这将非常有用。 672 | 673 | > 限制条件 674 | > 675 | > 没有分页或排序,标签没有按字母顺序排序。此命令仅对 Tag 字段进行操作 。字符串返回小写并去除空格,但其他方面保持不变。 676 | 677 | #### 例子 678 | 679 | FT.TAGVALS idx myTag 680 | #### 参数 681 | - index :全文索引名称。索引必须先用 FT.CREATE 创建 682 | - filed_name:模式中定义的标签文件的名称。 683 | 684 | #### 返回值 685 | 数组回复:标签索引中所有不同的标签。 686 | 687 | #### 复杂度 688 | O(n),n 是标签字段的基数。 689 | 690 | ## Suggestions 691 | ### FT.SUGADD 692 | #### 格式 693 | 694 | FT.SUGADD {key} {string} {score} [INCR] [PAYLOAD {payload}] 695 | #### 描述 696 | 将建议字符串添加到自动完成建议字典。这与索引定义脱节,并将创建和更新建议词典留给用户。 697 | 698 | #### 例子 699 | 700 | FT.SUGADD ac "hello world" 1 701 | #### 参数 702 | - key : 建议字典键。 703 | - string : 我们索引的建议字符串 704 | - score : 建议字符串权重的浮点数 705 | - INCR :如果设置,我们将建议的现有条目增加给定的分数,而不是替换分数。这对于根据用户查询实时更新字典很有用 706 | - PAYLOAD {payload} :如果设置,我们会保存一个额外的有效负载和建议,可以通过将 WITHPAYLOADS 参数添加 到 707 | 708 | #### 返回值 709 | 整数回复:建议字典的当前大小。 710 | 711 | ### FT.SUGGET 712 | #### 格式 713 | 714 | FT.SUGGET {key} {prefix} [FUZZY] [WITHSCORES] [WITHPAYLOADS] [MAX num] 715 | #### 描述 716 | 获取前缀的完成建议。 717 | 718 | #### 例子 719 | 720 | FT.SUGGET ac hell FUZZY MAX 3 WITHSCORES 721 | #### 参数 722 | - key : 建议字典键。 723 | - prefix : 要完成的前缀 724 | - FUZZY :如果设置,我们会进行模糊前缀搜索,包括与发送的前缀 Levenshtein 距离为 1 的前缀 725 | - MAX num :如果设置,我们将结果限制为最大值 num (默认值:5)。 726 | - WITHSCORES :如果设置,我们还会返回每个建议的分数。这可用于合并来自多个实例的结果 727 | - WITHPAYLOADS :如果设置,我们返回与建议一起保存的可选有效负载。如果条目不存在有效负载,我们将返回空回复。 728 | #### 返回值 729 | Array Reply:匹配前缀的最佳建议列表,可选地在每个条目后加上分数 730 | 731 | ### FT.SUGDEL 732 | #### 格式 733 | 734 | FT.SUGDEL {key} {string} 735 | #### 描述 736 | 从建议索引中删除一个字符串。 737 | 738 | #### 例子 739 | 740 | FT.SUGDEL ac "hello world" 741 | #### 参数 742 | - key : 建议字典键。 743 | - string : 要删除的字符串 744 | #### 返回值 745 | 整数回复:如果找到并删除字符串,则为 1,否则为 0。 746 | 747 | ### FT.SUGLEN 748 | #### 格式 749 | 750 | FT.SUGLEN {key} 751 | #### 描述 752 | 获取自动完成建议字典的大小 753 | 754 | #### 例 755 | 756 | FT.SUGLEN ac 757 | #### 参数 758 | - key : 建议字典键。 759 | #### 返回值 760 | 整数回复:建议字典的当前大小。 761 | 762 | ## Synonym 763 | ### FT.SYNUPDATE 764 | #### 格式 765 | 766 | FT.SYNUPDATE [SKIPINITIALSCAN] ... 767 | #### 描述 768 | 更新同义词组。 769 | 770 | 该命令用于创建或更新具有附加术语的同义词组。只有在更新后被索引的文档才会受到影响。 771 | 772 | #### 参数 773 | - SKIPINITIALSCAN :如果设置,我们不扫描和索引。 774 | 775 | ### FT.SYNDUMP 776 | #### 格式 777 | 778 | FT.SYNDUMP 779 | #### 描述 780 | 转储同义词组的内容。 781 | 782 | 该命令用于转储同义词数据结构。返回同义词术语及其同义词组 ID 的列表。 783 | 784 | ### FT.SPELLCHECK 785 | #### 格式 786 | 787 | FT.SPELLCHECK {index} {query} 788 | [DISTANCE dist] 789 | [TERMS {INCLUDE | EXCLUDE} {dict} [TERMS ...]] 790 | #### 描述 791 | 对查询执行拼写更正,返回拼写错误的术语的建议。 792 | 793 | 有关 更多详细信息,请参阅 查询拼写更正 。 794 | 795 | #### 参数 796 | - index : 带有索引词的索引。 797 | - query :搜索查询。 798 | - TERMS :指定一个包含 ( INCLUDE ) 或排除 ( EXCLUDE ) 自定义词典,名为 {dict} . 有关管理自定义词典的信息 ,请参阅 、 和 。 FT.DICTADD FT.DICTDEL FT.DICTDUMP 799 | - DISTANCE :拼写建议的最大 Levenshtein 距离(默认值:1,最大值:4)。 800 | 801 | #### 返回值 802 | 一个数组,其中每个元素代表查询中拼写错误的术语。拼写错误的术语按它们在查询中的出现顺序排序。 803 | 804 | 反过来,每个拼写错误的术语是一个由常量字符串“TERM”、术语本身和拼写更正建议组成的 3 元素数组。 805 | 806 | 拼写更正数组中的每个元素都由建议的分数和建议本身组成。根据拼写错误的术语,建议数组按分数降序排列。 807 | 808 | 得分的计算方法是将建议词所在的文档数除以索引中的文档总数。可以通过将分数除以最高分数来标准化结果。 809 | 810 | #### 示例输出 811 | 812 | 1) 1) "TERM" 813 | 2) "{term1}" 814 | 3) 1) 1) "{score1}" 815 | 2) "{suggestion1}" 816 | 2) 1) "{score2}" 817 | 2) "{suggestion2}" 818 | . 819 | . 820 | . 821 | 2) 1) "TERM" 822 | 2) "{term2}" 823 | 3) 1) 1) "{score1}" 824 | 2) "{suggestion1}" 825 | 2) 1) "{score2}" 826 | 2) "{suggestion2}" 827 | . 828 | . 829 | . 830 | . 831 | . 832 | . 833 | ## Dictionary 834 | ### FT.DICTADD 835 | #### 格式 836 | 837 | FT.DICTADD {dict} {term} [{term} ...] 838 | #### 描述 839 | 将术语添加到字典中。 840 | 841 | #### 参数 842 | - dict : 字典名称。 843 | - term :要添加到字典中的术语。 844 | 845 | c 846 | 返回 int,特别是添加的新术语的数量。 847 | 848 | ### FT.DICTDEL 849 | #### 格式 850 | 851 | FT.DICTDEL {dict} {term} [{term} ...] 852 | #### 描述 853 | 从字典中删除术语。 854 | 855 | #### 参数 856 | - dict : 字典名称。 857 | - term : 要从字典中删除的术语。 858 | 859 | #### 返回值 860 | 返回 int,特别是被删除的术语数。 861 | 862 | ### FT.DICTDUMP 863 | #### 格式 864 | 865 | FT.DICTDUMP {dict} 866 | #### 描述 867 | 转储给定字典中的所有术语。 868 | 869 | #### 参数 870 | dict : 字典名称。 871 | #### 返回值 872 | 返回一个数组,其中每个元素都是 term(字符串)。 873 | 874 | ## Info 875 | ### FT.INFO 876 | #### 格式 877 | 878 | FT.INFO {index} 879 | #### 描述 880 | 返回有关索引的信息和统计信息。返回值包括: 881 | 882 | - index_definition : FT.CREATE 命令参数的反映 。 883 | - fields : 索引模式 - 字段名称、类型和属性。 884 | - 文件数。 885 | - 不同术语的数量。 886 | - 每条记录的平均字节数。 887 | - 索引缓冲区的大小和容量。 888 | - 索引状态和百分比以及失败: 889 | - indexing : 是否在后台扫描索引, 890 | - percent_indexed :后台索引的进度(如果完成则为1),hash_indexing_failures :由于操作与索引架构不兼容而导致的失败次数。 891 | 892 | 可选的 893 | 894 | - garbage collector 除 NOGC 之外的所有选项的 统计信息 。 895 | - 有关 cursors 索引是否存在游标的统计信息 。 896 | - 有关 stopword lists 是否使用自定义停用词列表的统计信息 。 897 | 898 | #### 例子 899 | 900 | 127.0.0.1:6379> ft.info wik{0} 901 | 1) index_name 902 | 2) wikipedia 903 | 3) index_options 904 | 4) (empty array) 905 | 5) index_definition 906 | 6) 1) key_type 907 | 2) HASH 908 | 3) prefixes 909 | 4) 1) thing: 910 | 5) filter 911 | 6) startswith(@__key, "thing:") 912 | 7) language_field 913 | 8) __language 914 | 9) default_score 915 | 10) "1" 916 | 11) score_field 917 | 12) __score 918 | 13) payload_field 919 | 14) __payload 920 | 7) fields 921 | 8) 1) 1) title 922 | 2) type 923 | 3) TEXT 924 | 4) WEIGHT 925 | 5) "1" 926 | 6) SORTABLE 927 | 2) 1) body 928 | 2) type 929 | 3) TEXT 930 | 4) WEIGHT 931 | 5) "1" 932 | 3) 1) id 933 | 2) type 934 | 3) NUMERIC 935 | 4) 1) subject location 936 | 2) type 937 | 3) GEO 938 | 9) num_docs 939 | 10) "0" 940 | 11) max_doc_id 941 | 12) "345678" 942 | 13) num_terms 943 | 14) "691356" 944 | 15) num_records 945 | 16) "0" 946 | 17) inverted_sz_mb 947 | 18) "0" 948 | 19) total_inverted_index_blocks 949 | 20) "933290" 950 | 21) offset_vectors_sz_mb 951 | 22) "0.65932846069335938" 952 | 23) doc_table_size_mb 953 | 24) "29.893482208251953" 954 | 25) sortable_values_size_mb 955 | 26) "11.432285308837891" 956 | 27) key_table_size_mb 957 | 28) "1.239776611328125e-05" 958 | 29) records_per_doc_avg 959 | 30) "-nan" 960 | 31) bytes_per_record_avg 961 | 32) "-nan" 962 | 33) offsets_per_term_avg 963 | 34) "inf" 964 | 35) offset_bits_per_record_avg 965 | 36) "8" 966 | 37) hash_indexing_failures 967 | 38) "0" 968 | 39) indexing 969 | 40) "0" 970 | 41) percent_indexed 971 | 42) "1" 972 | 43) gc_stats 973 | 44) 1) bytes_collected 974 | 2) "4148136" 975 | 3) total_ms_run 976 | 4) "14796" 977 | 5) total_cycles 978 | 6) "1" 979 | 7) average_cycle_time_ms 980 | 8) "14796" 981 | 9) last_run_time_ms 982 | 10) "14796" 983 | 11) gc_numeric_trees_missed 984 | 12) "0" 985 | 13) gc_blocks_denied 986 | 14) "0" 987 | 45) cursor_stats 988 | 46) 1) global_idle 989 | 2) (integer) 0 990 | 3) global_total 991 | 4) (integer) 0 992 | 5) index_capacity 993 | 6) (integer) 128 994 | 7) index_total 995 | 8) (integer) 0 996 | 47) stopwords_list 997 | 48) 1) "tlv" 998 | 2) "summer" 999 | 3) "2020" 1000 | #### 参数 1001 | - index :全文索引名称。索引必须先用 FT.CREATE 创建 1002 | #### 复杂度 1003 | O(1) 1004 | 1005 | #### 返回值 1006 | 阵列响应。键和值的嵌套数组。 1007 | 1008 | ### FT._LIST 1009 | #### 格式 1010 | 1011 | FT._LIST 1012 | #### 描述 1013 | 返回所有现有索引的列表。 1014 | 1015 | #### 例子 1016 | 1017 | FT._LIST 1018 | 1) "idx" 1019 | 2) "movies" 1020 | 3) "imdb" 1021 | #### 复杂度 1022 | O(n) 其中 n 是系统中的索引数。 1023 | 1024 | #### 返回值 1025 | 具有索引名称的数组。 1026 | 1027 | >临时命令 1028 | > 1029 | >_ 命令中 的前缀 表示,这是一个临时命令。 1030 | >以后 SCAN 会增加一种 命令,用于数据库包含大量索引的情况。 1031 | 1032 | ## 配置 1033 | ### FT.CONFIG 1034 | #### 格式 1035 | 1036 | FT.CONFIG {option} 1037 | FT.CONFIG SET {option} {value} 1038 | #### 描述 1039 | 检索、描述和设置运行时配置选项。 1040 | 1041 | #### 参数 1042 | - option : 配置选项的名称,或 '*' 表示所有。 1043 | - value : 配置选项的值。有关配置选项的详细信息,请参阅 配置 。这些配置选项支持在运行时设置值: 1044 | - NOGC 1045 | - MINPREFIX 1046 | - MAXEXPANSIONS 1047 | - TIMEOUT 1048 | - ON_TIMEOUT 1049 | - MIN_PHONETIC_TERM_LEN 1050 | 1051 | #### 返回值 1052 | 当提供有效的选项名称时, GET 子命令返回一个带有当前选项值的字符串。当提供 '*' 时,将返回一个包含每个配置选项的数组的数组,该数组由选项的名称和当前值组成。 1053 | 1054 | SET 对于有效的运行时可设置选项名称和值 , 子命令返回“OK”。 1055 | 1056 | ## 过期命令 1057 | ### FT.ADD 1058 | #### 格式 1059 | 1060 | FT.ADD {index} {docId} {score} 1061 | [REPLACE [PARTIAL] [NOCREATE]] 1062 | [LANGUAGE {language}] 1063 | [PAYLOAD {payload}] 1064 | [IF {condition}] 1065 | FIELDS {field} {value} [{field} {value}...] 1066 | #### 描述 1067 | >弃用警告 1068 | > 1069 | >此命令已弃用,并充当简单的 redis HSET,仅当创建的文档与一个或某些索引定义(如 ft.create 中定义的 )匹配时,才会对其编制索引 ,请改用HSET 。 1070 | 1071 | 将文档添加到索引。 1072 | 1073 | #### 例子 1074 | 1075 | FT.ADD idx doc1 1.0 FIELDS title "hello world" 1076 | #### 参数 1077 | - index :全文索引名称。索引必须先用 FT.CREATE 创建 1078 | - docId :将从搜索中返回的文档 ID。 1079 | 1080 | >关于 docId 的说明 1081 | > 1082 | >同一个 docId 不能两次添加到同一个索引中。可以将相同的 docId 添加到多个索引中,但具有该 docId 的单个文档会保存在数据库中。 1083 | 1084 | - score : 基于用户排名的文档排名。这必须介于 0.0 和 1.0 之间。在 v2.0 上,这将被转换为创建的哈希中的“__score”字段。 1085 | - REPLACE :如果设置,我们将执行 UPSERT 样式插入 - 并删除文档的旧版本(如果存在)。 1086 | - PARTIAL (仅适用于 REPLACE):如果设置,则不必指定所有字段进行重新索引。未提供给命令的字段将从文档的当前版本加载。此外,如果只设置了不可索引的字段、分数或有效负载 - 我们不会对文档进行完整的重新索引,这会快得多。 1087 | - NOCREATE (仅适用于 REPLACE):如果设置,则文档仅在已存在时更新和重新索引。如果文档不存在,将返回错误。 1088 | - FIELDS :在 FIELDS 说明符之后,我们正在寻找 {field} {value} 要索引的成对 。每个字段都将根据 中给出的索引规范进行评分 FT.CREATE 。传递不在索引规范中的字段将使它们作为文档的一部分存储,或者如果设置了 NOSAVE 则被忽略 1089 | - PAYLOAD {payload} :可以选择为文档设置二进制安全有效负载字符串,可以在查询时通过自定义评分函数进行评估,或检索到客户端。在 v2.0 上,这将被转换为创建的哈希中的“__payload”字段。 1090 | - IF {condition} :(仅适用于 REPLACE 和可选 PARTIAL )。仅当布尔表达式适用于 更新前的文档时才更新 文档 ,例如 FT.ADD idx doc 1 REPLACE IF "@timestamp < 23323234234" 。 1091 | 1092 | 该表达式在更新之前被原子地计算,确保更新只有在它为真时才会发生。 1093 | 1094 | 有关 表达式语言的更多详细信息,请参阅 聚合 。 1095 | 1096 | - LANGUAGE language :如果设置,我们在索引期间对提供的语言使用词干分析器。默认为英文。如果发送了不受支持的语言,该命令将返回错误。支持的语言有: 1097 | 阿拉伯语、巴斯克语、加泰罗尼亚语、丹麦语、荷兰语、英语、芬兰语、法语、德语、希腊语、匈牙利语、印度尼西亚语、爱尔兰语、意大利语、立陶宛语、尼泊尔语、挪威语、葡萄牙语、罗马尼亚语、俄语、西班牙语、瑞典语、泰米尔语、土耳其语、中文 1098 | 1099 | 如果索引中文文档,您必须将语言设置为 chinese ,以便正确标记中文字符。在 v2.0 上,这将被转换为创建的哈希中的“__language”字段。 1100 | 1101 | #### 添加中文文档 1102 | 添加中文文档时, LANGUAGE chinese 应设置以便索引器正确标记术语。如果使用默认语言,则将根据标点符号和空格提取搜索词。中文分词器使用分段算法(通过 Friso ),该算法 对文本进行分段并对照预定义的字典进行检查。有关 更多信息,请参阅 词干 。 1103 | 1104 | #### 复杂度 1105 | O(n),其中 n 是文档中的标记数 1106 | 1107 | #### 返回值 1108 | 成功就OK,如果出现问题则出错。 1109 | 1110 | NOADD 如果 IF 条件评估为假,则返回 特殊状态 。 1111 | 1112 | > FT.ADD 与 REPLACE 和 PARTIAL 1113 | > 1114 | > 默认情况下,FT.ADD 不允许更新文档,如果它已存在于索引中,则会失败。但是,可以使用 REPLACE 和 REPLACE PARTIAL 选项更新文档。 REPLACE :单独将文档设置为新值,并重新索引它。任何未给出的字段都不会从文档的当前版本加载。 更换部分 :当两个参数都使用时,我们可以只更新部分文档字段,其余的将在重新索引之前加载。不仅如此,如果只更新分数、负载和非索引字段(使用 NOINDEX),我们实际上不会重新索引文档,只是在内部更新其元数据,这样会快很多并且不会产生索引垃圾。 1115 | 1116 | >覆盖其他键 1117 | > 1118 | >FT.ADD 实际上会使用给定的字段和值在 Redis 中创建一个散列。这意味着如果散列已经存在,它将被新值覆盖。 1119 | 1120 | ### FT.DEL 1121 | #### 格式 1122 | 1123 | FT.DEL {index} {doc_id} [DD] 1124 | #### 描述 1125 | >弃用警告 1126 | > 1127 | >此命令已弃用,用作简单的 redis DEL,删除的文档将从其索引的所有索引中删除”,请改用 DEL。 1128 | 1129 | 从索引中删除文档。如果文档在索引中,则返回 1,否则返回 0。 1130 | 1131 | >从 v2.0 开始,不再支持 [DD] 选项,删除一个文档意味着同时从 redis 中删除 hash 1132 | 1133 | >从 v2.0 开始,从一个索引中删除一个文档会导致该文档从包含它的所有索引中删除 1134 | 1135 | #### 例子 1136 | 1137 | FT.DEL idx doc1 1138 | #### 参数 1139 | - index : 索引名称。索引必须先用 FT.CREATE 创建 1140 | - doc_id : 要删除的文档的 id。它实际上不会删除存储文档的 HASH 键。如果需要,请使用 DEL 手动执行此操作。 1141 | #### 复杂度 1142 | O(1) 1143 | 1144 | #### 返回值 1145 | 整数回复:如果文档被删除,则为 1,否则为 0。 1146 | 1147 | ### FT.DROP 1148 | #### 格式 1149 | 1150 | FT.DROP {index} [KEEPDOCS] 1151 | #### 描述 1152 | >弃用警告 1153 | > 1154 | >此命令已弃用,请改用 FT.DROPINDEX。 1155 | 1156 | 删除索引和与其关联的所有键。 1157 | 1158 | 默认情况下,DROP 也会删除文档哈希,但添加 KEEPDOCS 选项可以将文档保持在原位,准备重新索引。 1159 | 1160 | 如果Redis实例上没有其他数据,这相当于FLUSHDB,除了不删除索引规范。 1161 | 1162 | #### 例子 1163 | 1164 | FT.DROP idx KEEPDOCS 1165 | #### 参数 1166 | - index :全文索引名称。索引必须先用 FT.CREATE 创建 1167 | - KEEPDOCS :如果设置,删除操作将不会删除实际的文档哈希。 1168 | #### 返回值 1169 | 状态回复:成功就OK。 1170 | 1171 | ### FT.GET 1172 | #### 格式 1173 | 1174 | FT.GET {index} {doc id} 1175 | #### 描述 1176 | >弃用警告 1177 | > 1178 | >此命令已弃用。请改用 HGETALL。 1179 | 1180 | 返回没有属性字段(分数/语言/有效负载)插入的文档内容。 1181 | 1182 | 如果文档不存在或者不是 HASH 对象,我们返回一个 NULL 回复 1183 | 1184 | #### 例子 1185 | 1186 | FT.GET idx doc1 1187 | #### 参数 1188 | - index : 索引名称。索引必须先用 FT.CREATE 创建 1189 | - documentId :插入索引的文档的 id 1190 | #### 返回值 1191 | 数组回复:文档的字段名和值的键值对 1192 | 1193 | ### FT.MGET 1194 | #### 格式 1195 | 1196 | FT.MGET {index} {docId} ... 1197 | #### 描述 1198 | >弃用警告 1199 | > 1200 | >此命令已弃用。请改用 HGETALL。 1201 | 1202 | 返回没有属性字段(分数/语言/有效负载)插入的文档内容。 1203 | 1204 | 此外,它还允许在集群模式下更简单地实现获取文档。 1205 | 1206 | 我们返回一个数组,其元素数与发送到命令的键数完全相同。 1207 | 1208 | 反过来,每个元素都是表示文档的键值对数组。 1209 | 1210 | 如果文档未找到或不是有效的 HASH 对象,则其在父数组中的位置将填充为 Null 回复对象。 1211 | 1212 | #### 例子 1213 | 1214 | FT.MGET idx doc1 doc2 1215 | #### 参数 1216 | - index :全文索引名称。索引必须先用 FT.CREATE 创建 1217 | - documentIds :插入索引的请求文档的 id 1218 | #### 返回值 1219 | Array Reply:一个数组,其元素数与发送给命令的键数完全相同。其中的每个元素要么是表示文档的数组,要么是 Null(如果未找到)。 1220 | 1221 | #### FT.SYNADD 1222 | >弃用警告 1223 | > 1224 | >2.0及以上版本不再支持此命令,直接使用FT.SYNUPDATE。 1225 | 1226 | #### 格式 1227 | 1228 | FT.SYNADD ... 1229 | #### 描述 1230 | 添加同义词组。 1231 | 1232 | 该命令用于创建新的同义词组。该命令返回同义词组 ID,稍后可使用该 ID 向该同义词组添加其他术语。只有在添加操作后被索引的文档才会受到影响。 1233 | -------------------------------------------------------------------------------- /redisearch/4.Configuration.md: -------------------------------------------------------------------------------- 1 | #运行时配置 2 | RediSearch支持一些运行时配置选项,这些选项应该在加载模块时确定。之后会添加更多配置项。 3 | 4 | 5 | ##加载期间传递配置选项 6 | 通常,传递配置选项是通过在命令行中的–loadmodule参数后附加参数来完成的。loadmodule配置指的是Redis配置文件中的loadmodule配置项,或MODULE LOAD命令。例如: 7 | 8 | redis.conf: 9 | 10 | loadmodule redisearch.so OPT1 OPT2 11 | 12 | redis-cli: 13 | 14 | 127.0.0.6379> MODULE load redisearch.so OPT1 OPT2 15 | 16 | 命令行: 17 | 18 | $ redis-server --loadmodule ./redisearch.so OPT1 OPT2 19 | 20 | 21 | 22 | #在运行时设置配置选项 23 | 从版本v1.4.1开始,可通过 FT.CONFIG 命令在运行时设置配置。另外,该命令可用于查看当前运行时配置选项。 24 | 25 | ##RedisSearch配置选项 26 | + TIMEOUT 27 | 允许运行搜索查询的最长时间(以毫秒为单位)。如果超过此时间,将返回到目前为止累积的最大结果,或者返回一个错误,具体取决于使用ON_TIMEOUT超时设置的策略。可以通过将其设置为0来禁用超时。 28 | 29 | >这只在并发模式下工作,因此启用SAFEMODE将禁用此选项。 30 | 31 | 默认: 32 | 33 | 500 34 | 35 | 例子: 36 | 37 | $ redis-server --loadmodule ./redisearch.so TIMEOUT 100 38 | 39 | 40 | + ON_TIMEOUT {policy} 41 | 42 | 超过超时设置的查询的响应策略。有以下策略:RETURN:此策略将返回查询所累积的最高结果,直到查询超时为止。 43 | FAIL:当查询超过超时值时将返回错误。 44 | 45 | 默认: 46 | 47 | RETURN 48 | 例子: 49 | 50 | $ redis-server --loadmodule ./redisearch.so ON_TIMEOUT fail 51 | 52 | + SAFEMODE 53 | 54 | 在版本v1.6中已弃用。在此版本中,默认为SAFEMODE。如果您仍然想重新启用并发写入模式,请使用CONCURRENT_WRITE_MODE! 55 | 如果该参数出现,那么RediSearch将关闭并发查询处理,只用单线程中工作。 56 | 如果数据一致性要去很高,这将非常有用,并避免在查询时有删除文档操作,这可能导致暂时不一致的结果(即,没有返回正确的文档,因为它们在查询期间可能被删除)。 57 | 58 | 默认: 59 | 60 | Off (not present) 61 | 例子: 62 | 63 | $ redis-server --loadmodule ./redisearch.so SAFEMODE 64 | 65 | >在版本v1.6中已弃用。 66 | 67 | + CONCURRENT_WRITE_MODE 68 | 69 | 如果启用,写操作、查询将同时执行。目前,只有标记化部分是并发执行的。实际的写操作仍然需要持有Redis全局锁。 70 | 默认: 71 | 72 | disabled 73 | 例子: 74 | 75 | $ redis-server --loadmodule ./redisearch.so CONCURRENT_WRITE_MODE 76 | 77 | >在版本v1.6后支持。 78 | 79 | + EXTLOAD {file_name} 80 | 81 | 如果存在,则尝试从指定的文件路径加载重新搜索扩展动态库。有关详细信息,请参见扩展。 82 | 83 | 默认: 84 | 85 | None 86 | 例子: 87 | 88 | $ redis-server --loadmodule ./redisearch.so EXTLOAD ./ext/my_extension.so 89 | 90 | + MINPREFIX 91 | 92 | 允许的前缀查询的最小字符数(例如hel*)。将其设置为1可能会影响性能。 93 | 94 | 默认: 95 | 96 | 2 97 | 例子: 98 | 99 | $ redis-server --loadmodule ./redisearch.so MINPREFIX 3 100 | 101 | + MAXPREFIXEXPANSIONS 102 | 103 | 允许查询前缀的最大扩展数。设置得太高会导致性能问题。如果达到MAXPREFIXEXPANSIONS,查询将继续执行第一个获取的结果。 104 | 105 | 默认: 106 | 107 | 200 108 | 109 | 例子: 110 | 111 | $ redis-server --loadmodule ./redisearch.so MAXPREFIXEXPANSIONS 1000 112 | 113 | + MAXDOCTABLESIZE 114 | 115 | 用于存储文档的内部哈希表的最大值。注意,此配置不限制可以存储的文档数量,只限制哈希表内部数组的最大值。如果索引包含少量不断更新的文档,减少此属性可以减少内存开销。 116 | 117 | 默认: 118 | 119 | 1000000 120 | 121 | 例子: 122 | 123 | $ redis-server --loadmodule ./redisearch.so MAXDOCTABLESIZE 3000000 124 | 125 | + MAXSEARCHRESULTS 126 | 127 | 如果查询时使用了LIMIT,返回FT.SEARCH 命令查询的最大结果数 。将值设置为-1将删除限制。 128 | 129 | 默认: 130 | 131 | 1000000 132 | 133 | 例子: 134 | 135 | $ redis-server --loadmodule ./redisearch.so MAXSEARCHRESULTS 3000000 136 | 137 | + MAXAGGREGATERESULTS 138 | 139 | 如果聚合查询时使用了LIMIT,返回FT.AGGREGATE 命令的最大结果数 。将值设置为-1将删除限制。 140 | 141 | 默认: 142 | 143 | unlimited 144 | 145 | 例子: 146 | 147 | $ redis-server --loadmodule ./redisearch.so MAXAGGREGATERESULTS 3000000 148 | 149 | + FRISOINI {file_name} 150 | 151 | 如果存在,将从指定路径加载自定义汉语词典。有关详细信息,请参见使用自定义词典。 152 | 153 | 默认: 154 | 155 | 无 156 | 157 | 例子: 158 | 159 | $ redis-server --loadmodule ./redisearch.so FRISOINI /opt/dict/friso.ini 160 | 161 | + CURSOR_MAX_IDLE 162 | 163 | 可以设置游标存活的最大空闲时间(毫秒)。 164 | 165 | 默认: 166 | 167 | 300000 168 | 169 | 例子: 170 | 171 | $ redis-server --loadmodule ./redisearch.so CURSOR_MAX_IDLE 500000 172 | 173 | >在版本v1.6后支持。 174 | 175 | 176 | + PARTIAL_INDEXED_DOCS 177 | 178 | 启用/禁用Redis命令过滤器filter。过滤器优化哈希的部分更新,如果更改的字段不是schema的值,则可以避免哈希的重新索引。 179 | 180 | >Redis命令filter将在每个Redis命令上执行。虽然对过滤器进行了优化,但这将导致所有命令的延迟略有增加。 181 | 因此,这种配置最好用于部分索引文档,非索引字段且更新频繁。默认:0 182 | 183 | >在版本v2.0.0后支持。 184 | 185 | + GC_SCANSIZE 186 | 187 | 用于清理索引的内部gc的垃圾回收块大小。 188 | 189 | 默认: 190 | 191 | 100 192 | 193 | 例子: 194 | 195 | $ redis-server --loadmodule ./redisearch.so GC_SCANSIZE 10 196 | 197 | 198 | + GC_POLICY 199 | 200 | 垃圾回收策略,支持的策略有: 201 | FORK:使用fork线程进行垃圾收集(v1.4.1及更高版本)。这是自版本1.6.1以来的默认GC策略,非常适合于一般用途的工作负载。 202 | LEGACY:使用同步的进程。这非常适合于读取量大、附加量大、更新/删除很少的工作负载 203 | 204 | 默认: 205 | 206 | FORK 207 | 208 | 例子: 209 | 210 | $ redis-server --loadmodule ./redisearch.so GC_POLICY LEGACY 211 | 212 | >当gc策略是FORK时,它可以与下面的选项组合。 213 | 214 | 215 | + NOGC 216 | 217 | 如果设置了,将关闭所有索引的垃圾回收。主要用于调试和测试。 218 | 219 | 默认: 220 | 221 | 无 222 | 223 | 例子: 224 | 225 | redis-server --loadmodule ./redisearch.so NOGC 226 | 227 | + FORK_GC_RUN_INTERVAL 228 | 229 | 两次连续fork GC运行之间的间隔(秒)。 230 | 231 | 默认: 232 | 233 | 30 234 | 235 | 例子: 236 | 237 | $ redis-server --loadmodule ./redisearch.so GC_POLICY FORK FORK_GC_RUN_INTERVAL 60 238 | 239 | 240 | + FORK_GC_RETRY_INTERVAL 241 | 242 | 在gc失败时,RedisSearc将重试fork GC的时间间隔(秒)。通常,当redis fork api不允许同时创建多个fork时,可能会发生故障。 243 | 244 | 默认: 245 | 246 | 5 247 | 248 | 例子: 249 | 250 | $ redis-server --loadmodule ./redisearch.so GC_POLICY FORK FORK_GC_RETRY_INTERVAL 10 251 | 252 | >在版本v1.4.16后支持。 253 | 254 | + FORK_GC_CLEAN_THRESHOLD 255 | 256 | fork GC只有在未清理的文档数超过此阈值时才会开始清理,否则它将跳过此运行。虽然默认值是100,但强烈建议将其更改为更高的数字。 257 | 258 | 默认: 259 | 260 | 100 261 | 262 | 例子: 263 | 264 | $ redis-server --loadmodule ./redisearch.so GC_POLICY FORK FORK_GC_CLEAN_THRESHOLD 10000 265 | 266 | >在版本v1.4.16后支持。 267 | 268 | + UPGRADE_INDEX 269 | 270 | 此配置是为从v1.x版本升级索引而引入的特殊配置,称为“旧索引”。 271 | 需要为每个旧索引提供此配置选项,索引名称和索引描述的所有有效选项。如上所述ft.create的规则。有关详细信息,请参阅升级到版本v2.0。 272 | 273 | 例子: 274 | 275 | $ redis-server --loadmodule ./redisearch.so UPGRADE_INDEX idx PREFIX 1 tt LANGUAGE french LANGUAGE_FIELD MyLang SCORE 0.5 SCORE_FIELD MyScore PAYLOAD_FIELD MyPayload UPGRADE_INDEX idx1 276 | 277 | >如果RDB文件不包含配置中指定的旧索引,则会向日志文件中添加警告消息,并继续加载。 278 | >如果RDB文件包含未在配置中指定的旧索引,则加载将失败,服务器将无法启动。 -------------------------------------------------------------------------------- /redisearch/5.Development.md: -------------------------------------------------------------------------------- 1 | # RedisSearch开发 2 | RediSearch开发包括配置开发环境(可以是基于Linux或macOS的),构建RediSearch,运行测试用例和基准测试平台,调试RediSearch模块及其测试用例。 3 | 4 | ## 克隆git仓库 5 | 通过调用以下命令,可以克隆RedSearch模块及其子模块: 6 | 7 | git clone --recursive https://github.com/RediSearch/RediSearch.git 8 | 9 | ## 在独立环境中运行 10 | 在独立环境中开发有几个原因,比如保持工作站的整洁,以及为不同的Linux版本开发。对于一个单独的环境,最通用的选择是虚拟机(使用Vagrant设置虚拟机非常容易)。Docker更为灵活,因为它提供了一个几乎即时的解决方案: 11 | 12 | search=$(docker run -d -it -v $PWD:/build debian:buster bash) 13 | docker exec -it $search bash 14 | 15 | 然后,从容器上,cd到 /build目录并进行操作。 16 | 17 | 在这种模式下,所有安装都保留在Docker容器内。退出容器后,您可以使用上述命令docker exec 重新调用,也可以将容器 状态提交到图像并在稍后阶段重新调用: 18 | 19 | docker commit $search redisearch1 20 | docker stop $search 21 | search=$(docker run -d -it -v $PWD:/build rediseatch1 bash) 22 | docker exec -it $search bash 23 | 24 | 您可以为您选择的操作系统替换 debian:buster ,主机操作系统是最佳选择(因此您可以在构建后在主机上运行 RediSearch 二进制文件)。 25 | 26 | ## 安装必备条件 27 | 要构建和测试 RediSearch,需要安装多个软件包,具体取决于底层操作系统。目前,我们支持 Ubuntu/Debian、CentOS、Fedora 和 macOS。 28 | 29 | 首先,进入 RediSearch 目录。 30 | 31 | 如果已经安装 gnu make ,可以执行, 32 | 33 | 在 Linux 上: 34 | 35 | sudo make setup 36 | 在 macOS 上: 37 | 38 | make setup 39 | 或者,调用以下命令(对于Linux下sudo): 40 | 41 | ./deps/readies/bin/getpy2 42 | ./system-setup.py 43 | 请注意,system-setup.py 将使用本机包管理器和pip在您的系统上安装各种包 。 44 | 45 | 如果您想避免这种情况,您可以: 46 | 47 | - system-setup.py 手动检查和安装软件包, 48 | - 使用如上所述的独立环境, 49 | - 使用Python虚拟环境,然而不再独立环境下使用Python是敏感的: python2 -m virtualenv venv; . ./venv/bin/activate 50 | 51 | ## 安装Redis 52 | 根据经验,最好运行最新的 Redis 版本。 53 | 54 | 如果您的操作系统有 Redis 6.x 包,您可以使用操作系统包管理器安装它。 55 | 56 | 否则,您可以调用 sudo ./deps/readies/bin/getredis . sudo 在 macOS 可不用。 57 | 58 | ## 获得帮助 59 | make help 提供开发功能的快速摘要。 60 | 61 | ## 从源头构建 62 | make build 将构建 RediSearch。要启用单元测试,请添加 TEST=1 . 请注意,RediSearch 使用 CMake 作为其构建系统。 make build 将调用 CMake 和完成构建所需的后续 make 命令。使用 make clean 删除内置文件。 make clean ALL=1 将删除整个 RediSearch/build 目录。 63 | 64 | ## 诊断 CMake 65 | 要了解 CMake 决策过程,请添加 WHY=1 到 build 命令。CMake 将其中间文件存储在 RediSearch/build . 之后,可以使用: 66 | 67 | cd build 68 | make -n 69 | 或者: 70 | 71 | cd build 72 | make V=1 73 | 进一步诊断构建过程。 74 | 75 | ## 使用 RediSearch 运行 Redis 76 | 以下将运行 redis 并加载 RediSearch 模块。 77 | 78 | make run 79 | 您可以 redis-cli 在另一个终端中打开并与之交互。 80 | 81 | ## 运行测试 82 | 有几组单元测试:*C 测试用例,位于ests/ctests目录下,通过make c_tests运行. 83 | * C++ 测试用例(由 GTest 启用),位于tests/cpptests目录下 ,通过make cpp_tests运行. 84 | * Python 测试用例(由 RLTest 启用),位于 tests/pytests目录下 ,通过make pytest 运行. 85 | 86 | 可以通过命令make test来运行所有测试。可以使用TEST参数运行单个测试,例如 make test TEST=regex 。 87 | 88 | ## 调试 89 | 启动调试构建(启用符号信息和禁用优化),运行 make DEBUG=1 . 可以使用 make run DEBUG=1 调用 gdb . 除了在 gdb中设置断点的常用方法外,还可以使用 BB 宏在 RediSearch 代码中设置断点。只在gdb下运行时才能运行。 90 | 91 | 同样,Python 测试在单测试模式下,可以使用 BB() 测试内部的函数设置断点 。 92 | 93 | 94 | -------------------------------------------------------------------------------- /redisearch/6.Clients.md: -------------------------------------------------------------------------------- 1 | # RediSearch 客户端 2 | RediSearch有几种不同语言的客户端可供使用,是由Redis模块开发者和社区成员开发,客户端封装了RediSearch的API。 3 | 4 | ### 目前可用的客户端 5 | 6 | | 语言 | 客户端 | 作者 | 开源协议 | GitHub Stars | 7 | | ------ | ------ | ------ | ------ | ------ | 8 | | Python | [redisearch-py](https://github.com/RediSearch/redisearch-py) | [Redis Labs](https://redislabs.com/) | BSD | ![](https://img.shields.io/github/stars/RediSearch/redisearch-py.svg?style=social&label=Star&maxAge=2592000) | 9 | | Java (Jedis client library) | [JRediSearch](https://github.com/RediSearch/JRediSearch) | [Redis Labs](https://redislabs.com/) | BSD | ![](https://img.shields.io/github/stars/RediSearch/JRediSearch.svg?style=social&label=Star&maxAge=2592000) | 10 | | Java (Lettuce client library) | [lettusearch](https://github.com/RediSearch/lettusearch) | [Redis Labs](https://redislabs.com/) | Apache-2.0 | ![](https://img.shields.io/github/stars/RediSearch/lettusearch.svg?style=social&label=Star&maxAge=2592000) | 11 | | Java | [spring-redisearch](https://github.com/RediSearch/spring-redisearch) | [Redis Labs](https://redislabs.com/) | Apache-2.0 | ![](https://img.shields.io/github/stars/RediSearch/spring-redisearch.svg?style=social&label=Star&maxAge=2592000) | 12 | | Java | [redis-modules-java](https://github.com/dengliming/redis-modules-java) | [Redis Labs](https://redislabs.com/) | Apache-2.0 | ![](https://img.shields.io/github/stars/dengliming/redis-modules-java.svg?style=social&label=Star&maxAge=2592000) | 13 | | Go | [redisearch-go](https://github.com/RediSearch/redisearch-go) | [Redis Labs](https://redislabs.com/) | BSD | ![](https://img.shields.io/github/stars/RediSearch/redisearch-go.svg?style=social&label=Star&maxAge=2592000) | 14 | | JavaScript | [RedRediSearch](https://github.com/stockholmux/redredisearch) | [Kyle J. Davis](https://github.com/stockholmux) | MIT | ![](https://img.shields.io/github/stars/stockholmux/redredisearch.svg?style=social&label=Star&maxAge=2592000) | 15 | | JavaScript | [redis-redisearch](https://github.com/stockholmux/node_redis-redisearch) | [Kyle J. Davis](https://github.com/stockholmux) | MIT | ![](https://img.shields.io/github/stars/stockholmux/node_redis-redisearch.svg?style=social&label=Star&maxAge=2592000) | 16 | | TypeScript | [redis-modules-sdk](https://github.com/danitseitlin/redis-modules-sdk) | [Dani Tseitlin](https://github.com/danitseitlin) | BSD-3-Clause | ![](https://img.shields.io/github/stars/danitseitlin/redis-modules-sdk.svg?style=social&label=Star&maxAge=2592000) | 17 | | C# | [NRediSearch](https://libraries.io/nuget/NRediSearch) | [Marc Gravell](https://github.com/StackExchange/) | MIT | ![](https://img.shields.io/github/stars/StackExchange/StackExchange.Redis.svg?style=social&label=Star&maxAge=2592000) | 18 | | PHP | [redisearch-php (for RediSearch v1)](https://github.com/ethanhann/redisearch-php) | [Ethan Hann](https://github.com/ethanhann) | MIT | ![](https://img.shields.io/github/stars/ethanhann/redisearch-php.svg?style=social&label=Star&maxAge=2592000) | 19 | | PHP | [Redisearch (for RediSearch v2)](https://github.com/front/redisearch) | [Front](https://github.com/front/) | MIT | ![](https://img.shields.io/github/stars/front/redisearch.svg?style=social&label=Star&maxAge=2592000) | 20 | | Rust | [redisearch-api-rs](https://github.com/RediSearch/redisearch-api-rs) | [Redis Labs](https://redislabs.com/) | BSD | ![](https://img.shields.io/github/stars/RediSearch/redisearch-api-rs.svg?style=social&label=Star&maxAge=2592000) | 21 | | Ruby on Rails | [redi_search_rails](https://github.com/dmitrypol/redi_search_rails) | [Dmitry Polyakovsky](https://github.com/dmitrypol) | MIT | ![](https://img.shields.io/github/stars/dmitrypol/redi_search_rails.svg?style=social&label=Star&maxAge=2592000) | 22 | | Ruby | [redisearch-rb](https://github.com/vruizext/redisearch-rb) | [Victor Ruiz](https://github.com/vruizext) | MIT | ![](https://img.shields.io/github/stars/vruizext/redisearch-rb.svg?style=social&label=Star&maxAge=2592000) | 23 | | Ruby| [redi_search](https://github.com/npezza93/redi_search) | [Nick Pezza](https://github.com/dmitrypol) | MIT | ![](https://img.shields.io/github/stars/npezza93/redi_search.svg?style=social&label=Star&maxAge=2592000) | 24 | 25 | ### 其他可用客户端 26 | 27 | | 语言 | 客户端 | 作者 | 开源协议 | GitHub Stars | 备注 28 | | ------ | ------ | ------ | ------ | ------ | ------ | 29 | | Rust | [redisearch-api-rs](https://github.com/RediSearch/redisearch-api-rs) | [Redis Labs](https://redislabs.com/) | BSD | ![](https://img.shields.io/github/stars/RediSearch/redisearch-api-rs.svg?style=social&label=Star&maxAge=2592000) | Rust写的Redis模块客户端 | 30 | -------------------------------------------------------------------------------- /redisearch/7.Administration/1.GeneralAdministration.md: -------------------------------------------------------------------------------- 1 | # RediSearch管理指南 2 | 3 | RediSearch不需要任何配置即可工作,但是在Redis上运行RediSearch时需要注意一些事项。 4 | 5 | ## 持久化 6 | RediSearch支持基于RDB和AOF的持久化。 对于单纯RDB配置,除了标准Redis RDB配置之外,不需要任何特殊设置。 7 | 8 | ## AOF持久化 9 | 尽管RediSearch支持AOF持久化,但是从1.1.0版本开始,RediSearch不支持使用AOF重写技术的“经典AOF”模式。相反,它仅支持AOF和RDB的混合模式,在这种模式下,重写AOF日志会创建RDF文件,并在该文件后进行追加。 10 | 11 | 为RediSearch开启AOF持久化,需要再redis.conf中添加以下配置: 12 | ``` 13 | appendonly yes 14 | aof-use-rdb-preamble yes 15 | ``` 16 | 17 | ## 主从复制 18 | RediSearch天生支持复制,使用主从方式部署,RediSearch通过从实例实现高可用性。更重要的是,从实例可以用来搜索,分担读流量。 19 | 20 | ## 集群支持 21 | RediSearch无法在集群模式下正常工作。RediSearch的企业版支持集群模式,可以扩展到数百个节点,数十亿个文档和TB级数据量。RediSearch企业版可以从Redis Labs购买使用。访问[Redis Labs官网](https://redislabs.com/redis-enterprise-documentation/developing/modules/redisearch/)获取更多信息。 22 | -------------------------------------------------------------------------------- /redisearch/7.Administration/2.UpgradeTo2.0WhenRunningInRedisOSS.md: -------------------------------------------------------------------------------- 1 | # 在Redis OSS上升级RediSearch 2.0 2 | 3 | > 企业版升级请参考[此链接](https://docs.redislabs.com/latest/modules/redisearch/) 4 | 5 | RediSearch v2版本重构了索引与数据的同步方式。RediSearch 2.0追踪与索引描述想匹配的哈希,忽略哈希是怎么插入或改变的(HSET,HINCR,HDEL),而不再使用FT.ADD命令对文档建立索引。索引描述可以按照指定前缀过滤哈希,通过FILTER选项构造细粒度的过滤器。索引描述是在创建索引(ft.create)的时候定义。 6 | 7 | v1.x版本的索引(被称作旧索引)没有这样的索引描述。这就是为什么在升级到2.0时需要提供索引描述的原因。在升级到v2的过程中,你应该通过Redis模块配置添加索引描述,以便RediSearch 2.0能加载这些旧索引。 8 | 9 | ## UPGRADE_INDEX配置 10 | 11 | 升级索引配置允许你指定要升级的旧索引。它需要指定索引名称以及ft.create命令定义的所有哈希参数(注意,只有索引名称是必需的,其他参数默认值和ft.create命令参数默认值相同)。例如,你有一个名字为idx的旧索引,要升级到RediSearch 2.0,则需要在启动时添加以下配置: 12 | ``` 13 | redis-server --loadmodule redisearch.so UPGRADE_INDEX idx 14 | ``` 15 | 指定要升级的索引前缀也是允许的,例如,假设索引idx的所有文档都以idx:开头,则以下命令会升级旧索引idx 16 | ``` 17 | redis-server --loadmodule redisearch.so UPGRADE_INDEX idx PREFIX 1 idx: 18 | ``` 19 | 20 | ## 升级限制 21 | 22 | 升级过程的原理是,它用所配置的索引描述重新定义索引,然后重新索引数据。这带来一些限制: 23 | 24 | - 如果配置了NOSAVE,则不可以升级,因为要索引的数据不存在。 25 | - 如果同时有多个索引,你需要告诉RediSearch哈希和索引的对应关系,可以通过指定前缀或者使用过滤器。 26 | - 如果存在没被索引的哈希,则需要告诉RediSearch哪些哈希需要创建索引,可以通过指定前缀或者使用过滤器。 27 | -------------------------------------------------------------------------------- /redisearch/8.Reference/1.QuerySyntax.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sohutv/redisearch-docs/254a235f8babaddb1c522e845ffcec870d273482/redisearch/8.Reference/1.QuerySyntax.md -------------------------------------------------------------------------------- /redisearch/8.Reference/10.StemmingSupport.md: -------------------------------------------------------------------------------- 1 | # 词干提取 2 | 3 | RediSearch支持词干提取,即将单词的基本形式加入到索引。例如,查询“going”,也会返回包含“go”和“gone”的结果。 4 | 5 | 目前词干提取是基于Snowball词干库,该库支持大多数欧洲语言以及阿拉伯语和其他语言。我们希望尽快包含更多的语言(如果你需要支持特定语言,请提一个issue)。 6 | 7 | 其他详细信息请参考[Snowball网站](http://snowballstem.org/)。 8 | 9 | ## 支持的语言 10 | 11 | RediSearch支持下列语言的索引和查询: 12 | 13 | - 阿拉伯 14 | - 丹麦语 15 | - 荷兰语 16 | - 英语 17 | - 芬兰 18 | - 法语 19 | - 德语 20 | - 匈牙利 21 | - 义大利文 22 | - 挪威 23 | - 葡萄牙语 24 | - 罗马尼亚语 25 | - 俄语 26 | - 西班牙语 27 | - 瑞典 28 | - 泰米尔语 29 | - 土耳其 30 | - 中文(见下文) 31 | 32 | ## 中文支持 33 | 34 | 由于分词方式的不同,为中文文档创建索引不同于大多数其他语言。大多数语言可以使用空格或特定分隔符来分词,但在中文并不行。 35 | 36 | 中文分词的实现,是通过扫描输入文本并按照字典或预定义的术语表,检查每个字符或字符序列,找出最可能的匹配(基于相邻的字符)。 37 | 38 | RediSearch为此使用了Friso这个中文词库。这不需要其他配置,对用户是透明的。 39 | 40 | ## 使用定制的字典 41 | 42 | 如果需要使用自定义的字典,可以在加载模块时配置。FRISOINI选项可以指定friso.ini文件的位置,friso.ini文件包含了字典文件路径和相关配置。 43 | 注意,不存在默认的friso.ini文件位置。RediSearch带有其自己的friso.ini和字典文件,它们在构建时被编译到模块二进制文件中。 44 | -------------------------------------------------------------------------------- /redisearch/8.Reference/11.SynonymsSupport.md: -------------------------------------------------------------------------------- 1 | # 同义词支持 2 | 3 | ## 概述 4 | RediSearch支持同义词,即搜索由同义词数据结构定义的同义词单词。 5 | 6 | 同义词数据结构是组的集合,每个组由同义词构成。例如,以下同义词数据结构包含三个组,每组包含三个同义词: 7 | ``` 8 | {boy, child, baby} 9 | {girl, child, baby} 10 | {man, person, adult} 11 | ``` 12 | 当同义词数据结构包含以上三个组时,搜索“child”,就可能会返回包含“boy”,“girl”,“child”和“baby”的文档。 13 | 14 | ## 同义词搜索技术 15 | 16 | 我们使用HashMap将单词映射到同义词组ID。在索引创建过程中,我们检查当前单词是否存在于同义词HashMap中,如果存在,则获取该单词所有的同义词组ID。 17 | 18 | 对于每一个同义词组ID,我们将另一条记录加入到名为“\~\”的倒排索引中,这条记录包含和单词相同的信息。当执行一个查询,我们检查搜索词是否存在于同义词HashMap中,如果存在,则获取该单词所有的同义词组ID。对于每一个同义词组ID,我们搜索名为“\~\”的倒排索引,并返回合并后的结果。此技术确保我们返回给定单词的所有同义词。 19 | 20 | ## 并发处理 21 | 22 | 由于索引创建是在单独的线程执行,且同义词HashMap可能在索引创建期间发生变化,因此可能导致数据损坏,或者在索引创建或搜索过程中崩溃。为了解决这个问题,我们创建了HashMap的只读副本用于创建索引。只读副本通过引入计数维护。 23 | 24 | 只要同义词HashMap不变,原始HashMap就会保留对其只读副本的引用,因此不会被释放。一旦同义词HashMap内的数据发生变化,同义词HashMap会减少其只读副本的引用计数。这样可以确保当所有索引器都使用只读副本完成创建后,只读副本可以自动释放。同样还可以确保索引器下一次获取只读副本时,同义词HashMap可以创建一个新的副本(包含新数据)并返回。 25 | 26 | ## 举例 27 | 28 | ``` 29 | # Create an index 30 | > FT.CREATE idx schema t text 31 | 32 | # Create a synonym group 33 | > FT.SYNUPDATE idx group1 hello world 34 | 35 | # Insert documents 36 | > HSET foo t hello 37 | (integer) 1 38 | > HSET bar t world 39 | (integer) 1 40 | 41 | # Search 42 | > FT.SEARCH idx hello 43 | 1) (integer) 2 44 | 2) "foo" 45 | 3) 1) "t" 46 | 2) "hello" 47 | 4) "bar" 48 | 5) 1) "t" 49 | 2) "world" 50 | ``` 51 | -------------------------------------------------------------------------------- /redisearch/8.Reference/12.DocumentPayload.md: -------------------------------------------------------------------------------- 1 | # 文档负载 2 | 3 | 通常,RediSearch将文档存储为哈希键。但是如果你想对某些数据进行汇总或评分,我们可能希望将这些数据存储为内联负载。这将使我们能够以极低的成本评估文档的属性以进行评分。 4 | 5 | 由于评分功能已经访问了文档元数据,其中包含了文档标志和评分,因此我们能够添加可在运行时评估的自定义负载。 6 | 7 | 负载不会被索引,且不会被引擎所处理。他们仅仅是为了在查询时被评估,并有选择的被检索出来。负载可以是JSON对象,字符串,或者你追求速度的话,可以是某种可以快速解码的二进制数据。 8 | 9 | ## 为文档添加负载 10 | 11 | 当使用FT.ADD插入文档,可以通过PAYLOAD关键字让RediSearch存储任意二进制安全的字符串作为文档负载。 12 | 13 | ``` 14 | FT.ADD {index_name} {doc_id} {score} PAYLOAD {payload} FIELDS {field} {data}... 15 | ``` 16 | 17 | ## 查询时间评估负载 18 | 19 | 带有评分功能的方法签名如下: 20 | ``` 21 | double (*ScoringFunction)(DocumentMetadata *dmd, IndexResult *h); 22 | ``` 23 | > 当前,评分功能不能动态添加,需要克隆引擎并替换他们。 24 | 25 | 文档元数据(DocumentMetaData )包含几个字段,其中一个是payload。它是任意长度的字节数组类型。 26 | ``` 27 | typedef struct { 28 | char *data, 29 | uint32_t len; 30 | } DocumentPayload; 31 | ``` 32 | 如果没有设置payload参数,则默认为NULL。如果设置了,则能对其解码。推荐对负载的一些元数据编码,比如大版本号等。 33 | 34 | ## 从文档中检索负载 35 | 36 | 查询时可能需要将文档的负载也查出来,这是通过对命令FT.SEARCH添加关键词WITHPAYLOADS实现的。 37 | 如果带有WITHPAYLOADS,则在返回结果中,负载在文档ID后面出现;如果同时带有 WITHSCORES ,则负载在评分后面出现。 38 | ``` 39 | 127.0.0.1:6379> FT.CREATE foo SCHEMA bar TEXT 40 | OK 41 | 127.0.0.1:6379> FT.ADD foo doc2 1.0 PAYLOAD "hi there!" FIELDS bar "hello" 42 | OK 43 | 127.0.0.1:6379> FT.SEARCH foo "hello" WITHPAYLOADS WITHSCORES 44 | 1) (integer) 1 45 | 2) "doc2" # id 46 | 3) "1" # score 47 | 4) "hi there!" # payload 48 | 5) 1) "bar" # fields 49 | 2) "hello" 50 | ``` 51 | -------------------------------------------------------------------------------- /redisearch/8.Reference/13.SpellingCorrection.md: -------------------------------------------------------------------------------- 1 | # 查询拼写纠正 2 | 3 | 查询拼写纠正为拼写错误的搜索字词提供了建议。例如,术语“reids”可能是拼错的“redis”。 4 | 5 | 在这种情况下,从1.4版本开始,RediSearch可为拼写错误的查询词生成替代词,拼写错误的查询词是满足如下条件的全文搜索词: 6 | 7 | - 不是停用词 8 | - 不在索引中 9 | - 至少3个字符 10 | 11 | 拼写错误的术语的替代词是从已被索引的术语的语料库以及一个或多个字典中生成的。替代词将根据其与拼写错误单词之间的莱文斯坦距离(LD)变为拼写纠正建议。根据拼写纠正建议在索引中的出现情况,为每个建议提供归一化分数。 12 | 13 | 要获取查询的拼写纠正,请参考[FT.SPELLCHECK](https://oss.redislabs.com/redisearch/Commands/#ftspellcheck)命令的文档。 14 | 15 | ## 自定义字典 16 | 17 | 字典是术语的集合。字典可以增加,删除术语,并分别使用FT.DICTADD,FT.DICTDEL和FT.DICTDUMP命令来转储其全部内容。 18 | 19 | 通过将字典中的内容从潜在拼写纠正建议中添加或排除,字典可以修改RediSearch的查询拼写纠正行为。 20 | 21 | 当用于术语包含时,字典中的术语可以作为拼写建议提供,无论它们在索引中是否出现(或缺少)。 包含字典的建议分数始终为0。 22 | 23 | 相反,被排除字典中的术语绝不会作为拼写替代形式返回。 24 | -------------------------------------------------------------------------------- /redisearch/8.Reference/14.PhoneticMatching.md: -------------------------------------------------------------------------------- 1 | # 语音匹配 2 | 3 | 语音匹配,可以根据其发音来搜索术语。 当搜索人的姓名时,此功能可能是有用的工具。 4 | 5 | 语音匹配基于语音算法。语音算法会将输入项转换为其发音的近似表示。这允许将术语加入索引,并按照发音进行搜索。 6 | 7 | 从1.4版本开始,RediSearch提供语音匹配功能,通过定义带有PHONETIC属性的文本。这使得这些字段中的术语的文本值和近似发音都被添加到索引。 8 | 9 | 默认情况下,在PHONETIC标记的字段上执行搜索也会返回语音上相似的结果。这个行为可通过查询属性[$phonetic](https://oss.redislabs.com/redisearch/Query_Syntax/#query_attributes) 控制。 10 | 11 | ## 语音算法支持 12 | 13 | RediSearch目前仅支持一个语音算法,即[Double Metaphone (DM)](https://en.wikipedia.org/wiki/Metaphone#Double_Metaphone),使用了[slacy/double-metaphone](https://github.com/slacy/double-metaphone)的实现,其提供了对拉丁语言的一般支持。 14 | -------------------------------------------------------------------------------- /redisearch/8.Reference/2.Stop-Words.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sohutv/redisearch-docs/254a235f8babaddb1c522e845ffcec870d273482/redisearch/8.Reference/2.Stop-Words.md -------------------------------------------------------------------------------- /redisearch/8.Reference/3.Aggregations.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sohutv/redisearch-docs/254a235f8babaddb1c522e845ffcec870d273482/redisearch/8.Reference/3.Aggregations.md -------------------------------------------------------------------------------- /redisearch/8.Reference/4.Tokenization and Escaping.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sohutv/redisearch-docs/254a235f8babaddb1c522e845ffcec870d273482/redisearch/8.Reference/4.Tokenization and Escaping.md -------------------------------------------------------------------------------- /redisearch/8.Reference/5.Sortable Values.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sohutv/redisearch-docs/254a235f8babaddb1c522e845ffcec870d273482/redisearch/8.Reference/5.Sortable Values.md -------------------------------------------------------------------------------- /redisearch/8.Reference/6.Tag Fields.md: -------------------------------------------------------------------------------- 1 | # 标签字段 2 | RediSearch 0.91 版本添加了一个新的字段——标签字段。它类似于全文字段,但在索引中使用更简单的标记化和编码。这些字段中的值无法通过一般的无字段搜索访问,只能与特殊语法一起使用。 3 | 4 | 标签和全文字段之间的主要区别是: 5 | 6 | 1. 我们不对标签索引执行词干提取。 7 | 2. 标记化更简单:用户可以为多个标签确定一个分隔符(默认为逗号),我们只在标签末尾进行空格修剪。因此,标签可以包含空格、标点符号、重音符号等。我们执行的仅有的两个转换是小写(目前仅适用于拉丁语言)和空格修剪。 8 | 3. 无法从一般全文搜索中找到标签。如果文档有一个名为“tags”的字段,其值为“foo”和“bar”,搜索 foo 或 bar 没有特殊的标签修饰符(见下文)将不会返回此文档。 9 | 4. 索引更简单,更压缩:我们不存储频率,字段标志的偏移向量。该索引仅包含编码为增量的文档 ID。这意味着标签索引中的条目通常为一或两个字节长。这使它们非常高效和快速。 10 | 5. 每个索引可以创建无限数量的标签字段,只要字段总数低于 1024。 11 | 12 | ## 创建标签字段 13 | 可以使用以下语法将标记字段添加到 FT.ADD 中的架构中: 14 | 15 | 16 | FT.CREATE ... SCHEMA ... {field_name} TAG [SEPARATOR {sep}] 17 | SEPARATOR 默认为逗号 ( , ),可以是任何可打印的 ASCII 字符。例如: 18 | 19 | 20 | FT.CREATE idx ON HASH PREFIX 1 test: SCHEMA tags TAG SEPARATOR ";" 21 | 22 | ## 查询标签字段 23 | 如上所述,仅搜索没有任何修饰符的标签将不会检索包含它的文档。 24 | 25 | 查询中匹配标签的语法如下(在这种情况下,大括号是语法的一部分): 26 | 27 | @:{ | | ...} 28 | 29 | 例如,此查询查找带有标记 hello world 或 的 文档 foo bar : 30 | 31 | 32 | FT.SEARCH idx "@tags:{ hello world | foo bar }" 33 | 标记子句可以组合成任何子句,用作否定表达式、可选表达式等。例如,给定以下索引: 34 | 35 | 36 | FT.CREATE idx ON HASH PREFIX 1 test: SCHEMA title TEXT price NUMERIC tags TAG SEPARATOR ";" 37 | 您可以将 标题 字段上的全文搜索、 价格 上的数字范围 结合起来 ,并 像这样匹配 foo bar 或 hello world 标签: 38 | 39 | 40 | FT.SEARCH idx "@title:hello @price:[0 100] @tags:{ foo bar | hello world } 41 | 42 | ## 单个过滤器中的多个标签 43 | 请注意,在同一个子句中包含多个标签会创建包含任何包含标签的所有文档的联合。要创建包含 所有 给定标签的文档的交集 ,您应该多次重复标签过滤器。 44 | 45 | 例如,假设有一个旅行者索引,每个旅行者访问过的城市都有一个标签字段: 46 | 47 | FT.CREATE myIndex ON HASH PREFIX 1 traveller: SCHEMA name TEXT cities TAG 48 | 49 | HSET traveller:1 name "John Doe" cities "New York, Barcelona, San Francisco" 50 | 对于此索引,以下查询将返回 至少访问过 以下城市之一 的所有人 : 51 | 52 | 53 | FT.SEARCH myIndex "@cities:{ New York | Los Angeles | Barcelona }" 54 | 但是下一个查询将返回所有访问过 所有三个城市的人 : 55 | 56 | 57 | FT.SEARCH myIndex "@cities:{ New York } @cities:{Los Angeles} @cities:{ Barcelona }" 58 | 59 | ## 在标签中包含标点符号 60 | 标签可以包含除字段分隔符之外的标点符号(默认情况下,逗号)。使用该 HSET 命令将值添加到 Redis 哈希时,您不需要转义标点符号 。 61 | 62 | 例如,给定以下索引: 63 | 64 | 65 | FT.CREATE punctuation ON HASH PREFIX 1 test: SCHEMA tags TAG 66 | 您可以添加包含标点符号的标签,如下所示: 67 | 68 | 69 | HSET test:1 tags "Andrew's Top 5,Justin's Top 5" 70 | 但是,当您查询包含标点符号的标签时,您必须使用反斜杠字符 ( \ )对该标点符号进行转义 。 71 | 72 | 注意 :在大多数语言中,您需要一个额外的反斜杠。在 redis-cli 中也是如此。 73 | 74 | 例如, Andrew's Top 5 在 redis-cli 中查询标签 如下所示: 75 | 76 | 77 | FT.SEARCH punctuation "@tags:{ Andrew\\'s Top 5 }" 78 | 79 | ## 包含多个单词的标签 80 | 正如本文档中的示例所示,单个标签可以包含多个单词。我们建议您在查询时转义空格,尽管这样做不是必需的。 81 | 82 | 转义空格的方式与转义标点符号的方式相同——在空格前加一个反斜杠字符(或两个反斜杠,取决于编程语言和环境)。 83 | 84 | 因此,在 redis-cli 中查询时,您将像这样转义“成为或不成为”标签: 85 | 86 | 87 | FT.SEARCH idx "@tags:{ to\\ be\\ or\\ not\\ to\\ be }" 88 | 您应该对空格进行转义,因为如果一个标签包含多个单词并且其中一些是 “to”或“be”等 停用词 ,那么包含这些单词但没有转义空格的查询将产生语法错误。 89 | 90 | 您可以在以下示例中看到它的样子: 91 | 92 | 93 | 127.0.0.1:6379> FT.SEARCH idx "@tags:{ to be or not to be }" 94 | (error) Syntax error at offset 27 near be 95 | 注意: 停用词是很常见的词,以至于搜索引擎会忽略它们。 如果您想了解更多信息,我们有一个关于 RediSearch 中停用词 的专门页面 。 96 | 97 | 鉴于存在语法错误的可能性,我们建议您对标签查询中的所有空格进行转义。 -------------------------------------------------------------------------------- /redisearch/8.Reference/7.Highlighting Results.md: -------------------------------------------------------------------------------- 1 | # 高亮API 2 | 突出显示 API 允许您仅将与搜索查询匹配的文档的相关部分作为结果返回。这允许用户快速查看文档与他们的查询的关系,搜索词通常以粗体突出显示。 3 | 4 | RediSearch 使用以下 API 实现高性能突出显示和摘要算法: 5 | 6 | ## 命令语法 7 | 8 | FT.SEARCH ... 9 | SUMMARIZE [FIELDS {num} {field}] [FRAGS {numFrags}] [LEN {fragLen}] [SEPARATOR {sepstr}] 10 | HIGHLIGHT [FIELDS {num} {field}] [TAGS {openTag} {closeTag}] 11 | 有两个子命令用于高亮显示。一种是 HIGHLIGHT 用打开和/或关闭标签包围匹配的文本,另一种是 SUMMARIZE 将字段拆分为围绕找到的术语的上下文片段。可以在同一查询中汇总字段、突出显示字段或执行这两种操作。 12 | 13 | ###总结 14 | 15 | FT.SEARCH ... 16 | SUMMARIZE [FIELDS {num} {field}] [FRAGS {numFrags}] [LEN {fragLen}] [SEPARATOR {sepStr}] 17 | 摘要会将文本分成更小的片段;每个片段将包含找到的术语和一些额外的周围上下文。 18 | 19 | RediSearch 可以使用 SUMMARIZE 关键字进行汇总 。如果未传递其他参数, 则使用内置默认值汇总所有 返回的字段 。 20 | 21 | 该 SUMMARIZE 关键字接受以下参数: 22 | 23 | - FIELDS : 如果存在,必须是第一个参数。后面应该是要汇总的字段数,后面是字段列表。总结了每个存在的字段。如果未 FIELDS 传递指令,则 汇总返回的 所有 字段。 24 | - FRAGS : 应该返回多少片段。如果未指定,则使用默认值 3。 25 | - LEN 每个片段应包含的上下文单词数。上下文词围绕找到的术语。较高的值将返回较大的文本块。如果未指定,则默认值为 20。 26 | - SEPARATOR 用于分隔各个摘要片段的字符串。默认是 ... 搜索引擎中常见的;但是如果您希望稍后以编程方式将它们分开,您可以使用任何其他字符串覆盖它。您可以使用换行符序列,因为换行符无论如何都会从结果正文中删除(因此,它不会与文本中嵌入的换行符混淆) 27 | 28 | ### 突出显示 29 | 30 | FT.SEARCH ... HIGHLIGHT [FIELDS {num} {field}] [TAGS {openTag} {closeTag}] 31 | 突出显示将使用用户定义的标签突出显示找到的术语(及其变体)。这可用于使用标记语言以不同字体显示匹配的文本,或以其他方式使文本显示不同。 32 | 33 | RediSearch 可以使用 HIGHLIGHT 关键字进行高亮显示 。如果未传递其他参数, 则使用内置默认值突出显示所有 返回的字段 。 34 | 35 | 该 HIGHLIGHT 关键字接受以下参数: 36 | 37 | - FIELDS 如果存在,则必须是第一个参数。后面应该是要突出显示的字段数,后面是字段列表。每个存在的字段都突出显示。如果没有 FIELDS 传递指令,则 所有 返回的字段都将突出显示。 38 | - TAGS 如果存在,后面必须跟两个字符串;第一个附加到每个术语匹配,第二个附加到它。如果未 TAGS 指定,则附加和前置一个内置标记值。 39 | 40 | #### 字段选择 41 | 如果没有特定的字段被传递到 RETURN , SUMMARIZE 或 HIGHLIGHT 关键字,然后文档的所有字段都返回。但是,如果这些关键字中的任何一个包含 FIELD 指令,则该 SEARCH 命令将仅返回在任何这些指令中枚举的所有字段的总和。 42 | 43 | 所述 RETURN 关键字被特殊处理,因为它覆盖在指定的任何字段 SUMMARIZE 或 HIGHLIGHT 。 44 | 45 | 在 command 中 RETURN 1 foo SUMMARIZE FIELDS 1 bar HIGHLIGHT FIELDS 1 baz ,字段 foo 按原样返回,而 bar 和 baz 不返回,因为 RETURN 已指定,但不包括这些字段。 46 | 47 | 在命令中 SUMMARIZE FIELDS 1 bar HIGHLIGHT FIELDS 1 baz , bar 返回汇总并 baz 突出显示。 -------------------------------------------------------------------------------- /redisearch/8.Reference/8.Scoring Documents.md: -------------------------------------------------------------------------------- 1 | # RediSearch的评分 2 | RediSearch 带有一些非常基本的评分函数来评估文档相关性。它们都基于文档分数和术语频率。这与使用 可排序字段 的能力无关 。通过将 SCORER {scorer_name} 参数添加到搜索查询来指定评分函数 。 3 | 4 | 如果您更喜欢自定义评分函数,可以使用 扩展 API 添加更多函数 。 5 | 6 | 这些是 RediSearch 中可用的预捆绑评分函数及其工作原理。每个函数都由注册名称提及,可以作为 SCORER 参数在 FT.SEARCH . 7 | 8 | ## TFIDF(默认) 9 | 基本的 TF-IDF 评分, 其中包含一些额外的功能: 10 | 11 | 1. 对于每个结果中的每个词,我们计算该词对该文档的 TF-IDF 分数。频率根据预先确定的字段权重进行加权,每个词的频率 通过每个文档中的最高词频进行 归一化 。 12 | 2. 我们将查询词的总 TF-IDF 乘以给定的先验文档分数 FT.ADD 。 13 | 3. 我们根据搜索词之间的“倾斜”或累积距离对每个结果进行惩罚:完全匹配不会受到惩罚,但搜索词相距遥远的匹配会看到其得分显着降低。对于每 2 克连续项,我们找到它们之间的最小距离。惩罚是距离总和的平方根,平方 - 1/sqrt(d(t2-t1)^2 + d(t3-t2)^2 + ...) 。 14 | 15 | 因此,对于文档 D, 中的 N 个术语, T1...Tn 可以使用此 python 函数来描述结果分数: 16 | 17 | def get_score(terms, doc): 18 | # the sum of tf-idf 19 | score = 0 20 | 21 | # the distance penalty for all terms 22 | dist_penalty = 0 23 | 24 | for i, term in enumerate(terms): 25 | # tf normalized by maximum frequency 26 | tf = doc.freq(term) / doc.max_freq 27 | 28 | # idf is global for the index, and not calculated each time in real life 29 | idf = log2(1 + total_docs / docs_with_term(term)) 30 | 31 | score += tf*idf 32 | 33 | # sum up the distance penalty 34 | if i > 0: 35 | dist_penalty += min_distance(term, terms[i-1])**2 36 | 37 | # multiply the score by the document score 38 | score *= doc.score 39 | 40 | # divide the score by the root of the cumulative distance 41 | if len(terms) > 1: 42 | score /= sqrt(dist_penalty) 43 | 44 | return score 45 | 46 | ## TFIDF.DOCNORM 47 | 与默认的 TFIDF 评分器相同,但有一个重要区别: 48 | 49 | 词频通过文档的长度(表示为词的总数)进行归一化。长度是加权的,因此如果文档包含两个词,一个在权重为 1 的字段中,另一个在权重为 5 的字段中,则总频率为 6,而不是 2。 50 | 51 | 52 | FT.SEARCH myIndex "foo" SCORER TFIDF.DOCNORM 53 | 54 | ## BM25 55 | 基本 TF-IDF 记分器的变体,请参阅 此 Wikipedia 文章了解更多信息 。 56 | 57 | 我们还将每个文档的相关性分数乘以先验文档分数,并根据 TFIDF 中的 slop 应用惩罚。 58 | 59 | 60 | FT.SEARCH myIndex "foo" SCORER BM25 61 | 62 | ## DISMAX 63 | 一个简单的记分器,用于总结匹配项的频率;在 union 子句的情况下,它将给出这些匹配项的最大值。不适用其他处罚或因素。 64 | 65 | 它不是 Solr 的 DISMAX 算法的一对一实现, 而是从广义上遵循它。 66 | 67 | FT.SEARCH myIndex "foo" SCORER DISMAX 68 | 69 | ## DOCSCORE 70 | 一个评分函数,它只返回文档的先验分数,而不对其进行任何计算。由于文档分数可以更新,因此如果您想使用外部分数而不是其他分数,这会很有用。 71 | 72 | FT.SEARCH myIndex "foo" SCORER DOCSCORE 73 | 74 | ## HAMMING 75 | 通过文档负载和查询负载之间的(逆)汉明距离评分。由于我们对 最近的 邻居感兴趣,因此 我们对汉明距离 ( 1/(1+d) ) 进行逆运算, 因此距离为 0 的得分为 1,并且是最高等级。 76 | 77 | 这仅适用于: 78 | 79 | 1. 该文档具有有效负载。 80 | 2. 查询具有有效负载。 81 | 3. 两者 的长度完全相同 。 82 | 83 | 有效载荷是二进制安全的,并且具有长度为 64 位倍数的有效载荷会产生稍快的结果。 84 | 85 | 例子: 86 | 87 | 127.0.0.1:6379> FT.CREATE idx SCHEMA foo TEXT 88 | OK 89 | 127.0.0.1:6379> FT.ADD idx 1 1 PAYLOAD "aaaabbbb" FIELDS foo hello 90 | OK 91 | 127.0.0.1:6379> FT.ADD idx 2 1 PAYLOAD "aaaacccc" FIELDS foo bar 92 | OK 93 | 94 | 127.0.0.1:6379> FT.SEARCH idx "*" PAYLOAD "aaaabbbc" SCORER HAMMING WITHSCORES 95 | 1) (integer) 2 96 | 2) "1" 97 | 3) "0.5" // hamming distance of 1 --> 1/(1+1) == 0.5 98 | 4) 1) "foo" 99 | 2) "hello" 100 | 5) "2" 101 | 6) "0.25" // hamming distance of 3 --> 1/(1+3) == 0.25 102 | 7) 1) "foo" 103 | 2) "bar" -------------------------------------------------------------------------------- /redisearch/8.Reference/9.Extension API.md: -------------------------------------------------------------------------------- 1 | # 扩展 RediSearch 2 | RediSearch 支持扩展机制,就像 Redis 支持模块一样。目前该 API 非常小,尚不支持在运行时动态加载扩展。相反,扩展必须用 C(或具有 C 接口的语言)编写并编译成将在运行时加载的动态库。 3 | 4 | 目前有两种扩展 API: 5 | 6 | 1. Query Expanders ,其作用是扩展查询标记(即词干分析器)。 7 | 2. Scoring Functions ,其作用是在查询时间内对搜索结果进行排名。 8 | 9 | ## 注册和加载扩展 10 | 扩展应该编译成 .so 文件,并在模块初始化时加载到 RediSearch 中。 11 | 12 | - 编译 13 | 14 | 扩展应作为动态库进行编译和链接。 可以在此处找到 扩展的示例 Makefile 。 15 | 16 | 该文件夹还包含一个用于测试的示例扩展,可作为实现您自己的扩展的框架。 17 | 18 | - 加载中 19 | 20 | 加载扩展是通过 在加载 RediSearch 时附加 EXTLOAD {path/to/ext.so} 在 loadmodule 配置指令之后来完成的。例如: 21 | 22 | sh $ redis-server --loadmodule ./redisearch.so EXTLOAD ./ext/my_extension.so 23 | 24 | 这会导致 RediSearch 自动加载扩展并注册其扩展器和记分器。 25 | 26 | ## 初始化扩展 27 | 扩展的入口点是一个具有以下签名的函数: 28 | 29 | 30 | int RS_ExtensionInit(RSExtensionCtx *ctx); 31 | 加载扩展时,RediSearch 会查找此函数并调用它。该函数负责注册和初始化扩展器和记分器。 32 | 33 | 它应该在错误时返回 REDISEARCH_ERR 或在成功时返回 REDISEARCH_OK。 34 | 35 | ### 示例初始化函数 36 | 37 | #include //must be in the include path 38 | 39 | int RS_ExtensionInit(RSExtensionCtx *ctx) { 40 | 41 | /* Register a scoring function with an alias my_scorer and no special private data and free function */ 42 | if (ctx->RegisterScoringFunction("my_scorer", MyCustomScorer, NULL, NULL) == REDISEARCH_ERR) { 43 | return REDISEARCH_ERR; 44 | } 45 | 46 | /* Register a query expander */ 47 | if (ctx->RegisterQueryExpander("my_expander", MyExpander, NULL, NULL) == 48 | REDISEARCH_ERR) { 49 | return REDISEARCH_ERR; 50 | } 51 | 52 | return REDISEARCH_OK; 53 | } 54 | 55 | ## 调用您的自定义函数 56 | 执行查询时,您可以通过使用给定别名指定 SCORER 或 EXPANDER 参数来告诉 RediSearch 使用您的评分器或扩展器。例如: 57 | 58 | FT.SEARCH my_index "foo bar" EXPANDER my_expander SCORER my_scorer 59 | 注意 :扩展器和记分器别名 区分大小写 。 60 | 61 | ## 查询扩展器 API 62 | 目前,我们只支持基本查询扩展,一次一个令牌。扩展器可以决定使用任意数量的令牌扩展任何给定的令牌,这些令牌将在查询时进行联合合并。 63 | 64 | 扩展器的 API 如下: 65 | 66 | 67 | #include //must be in the include path 68 | 69 | void MyQueryExpander(RSQueryExpanderCtx *ctx, RSToken *token) { 70 | ... 71 | } 72 | 73 | ### RSQueryExpanderCtx 74 | RSQueryExpanderCtx 是包含扩展私有数据的上下文,以及用于扩展查询的回调方法。它被定义为: 75 | 76 | 77 | typedef struct RSQueryExpanderCtx { 78 | 79 | /* Opaque query object used internally by the engine, and should not be accessed */ 80 | struct RSQuery *query; 81 | 82 | /* Opaque query node object used internally by the engine, and should not be accessed */ 83 | struct RSQueryNode **currentNode; 84 | 85 | /* Private data of the extension, set on extension initialization */ 86 | void *privdata; 87 | 88 | /* The language of the query, defaults to "english" */ 89 | const char *language; 90 | 91 | /* ExpandToken allows the user to add an expansion of the token in the query, that will be 92 | * union-merged with the given token in query time. str is the expanded string, len is its length, 93 | * and flags is a 32 bit flag mask that can be used by the extension to set private information on 94 | * the token */ 95 | void (*ExpandToken)(struct RSQueryExpanderCtx *ctx, const char *str, size_t len, 96 | RSTokenFlags flags); 97 | 98 | /* SetPayload allows the query expander to set GLOBAL payload on the query (not unique per token) 99 | */ 100 | void (*SetPayload)(struct RSQueryExpanderCtx *ctx, RSPayload payload); 101 | 102 | } RSQueryExpanderCtx; 103 | 104 | ### RSToken 105 | 106 | RSToken 表示要扩展的单个查询令牌,定义为: 107 | 108 | 109 | /* A token in the query. The expanders receive query tokens and can expand the query with more query 110 | * tokens */ 111 | typedef struct { 112 | /* The token string - which may or may not be NULL terminated */ 113 | const char *str; 114 | /* The token length */ 115 | size_t len; 116 | 117 | /* 1 if the token is the result of query expansion */ 118 | uint8_t expanded:1; 119 | 120 | /* Extension specific token flags that can be examined later by the scoring function */ 121 | RSTokenFlags flags; 122 | } RSToken; 123 | 124 | ## 评分函数API 125 | 评分函数接收由查询评估的每个文档,用于最终排名。它可以访问产生文档的所有查询词,以及有关文档的元数据,例如其先验分数、长度等。 126 | 127 | 由于评分函数是针对每个文档进行评估的,可能是数百万次,而且由于 redis 是单线程的,因此它必须尽可能快地运行并进行大量优化。 128 | 129 | 评分函数应用于每个潜在结果(每个文档),并使用以下签名实现: 130 | 131 | 132 | double MyScoringFunction(RSScoringFunctionCtx *ctx, RSIndexResult *res, 133 | RSDocumentMetadata *dmd, double minScore); 134 | RSScoringFunctionCtx 是一个实现了一些辅助方法的上下文。 135 | 136 | RSIndexResult 是结果信息 - 包含文档 ID、频率、术语和偏移量。 137 | 138 | RSDocumentMetadata 是一个保存有关文档的全局信息的对象,例如其先验分数。 139 | 140 | minSocre 是将产生与搜索相关的结果的最小分数。它可用于在我们开始之前停止处理中途。 141 | 142 | 函数的返回值是 double 表示结果的最终分数。返回 0 会导致对结果进行计数,但如果有分数大于 0 的结果,它们将出现在其上方。要完全过滤结果而不将其计入总数,记分员应返回特殊值 RS_SCORE_FILTEROUT (内部设置为负无穷大或 -1/0)。 143 | 144 | ### RSScoringFunctionCtx 145 | 这是一个包含以下成员的对象: 146 | 147 | - void *privdata :指向由扩展在初始化时设置的对象的指针。 148 | - RSPayload 负载 :由查询扩展器或客户端设置的负载对象。 149 | - int GetSlop(RSIndexResult *res) :一种回调方法,它产生查询词之间的总最小距离。这可用于首选“斜率”较小且术语彼此更接近的结果。 150 | 151 | ### RSIndexResult 152 | 这是一个对象,其中包含有关索引中当前结果的信息,它是导致当前文档被视为有效结果的所有术语的集合。 153 | 154 | 有关详细信息,请参阅 redisearch.h 155 | 156 | ### RSDocumentMetadata 157 | 这是一个描述与当前查询无关的全局信息的对象,该信息与评分函数正在评估的文档有关。 158 | 159 | ## 示例查询扩展器 160 | 此示例查询扩展器使用术语 foo 扩展每个标记: 161 | 162 | 163 | #include //must be in the include path 164 | 165 | void DummyExpander(RSQueryExpanderCtx *ctx, RSToken *token) { 166 | ctx->ExpandToken(ctx, strdup("foo"), strlen("foo"), 0x1337); 167 | } 168 | 169 | ## 评分函数示例 170 | 这是一个实际的评分函数,计算文档的 TF-IDF,乘以文档分数,然后除以斜率: 171 | 172 | 173 | #include //must be in the include path 174 | 175 | double TFIDFScorer(RSScoringFunctionCtx *ctx, RSIndexResult *h, RSDocumentMetadata *dmd, 176 | double minScore) { 177 | // no need to evaluate documents with score 0 178 | if (dmd->score == 0) return 0; 179 | 180 | // calculate sum(tf-idf) for each term in the result 181 | double tfidf = 0; 182 | for (int i = 0; i < h->numRecords; i++) { 183 | // take the term frequency and multiply by the term IDF, add that to the total 184 | tfidf += (float)h->records[i].freq * (h->records[i].term ? h->records[i].term->idf : 0); 185 | } 186 | // normalize by the maximal frequency of any term in the document 187 | tfidf /= (double)dmd->maxFreq; 188 | 189 | // multiply by the document score (between 0 and 1) 190 | tfidf *= dmd->score; 191 | 192 | // no need to factor the slop if tfidf is already below minimal score 193 | if (tfidf < minScore) { 194 | return 0; 195 | } 196 | 197 | // get the slop and divide the result by it, making sure we prefer results with closer terms 198 | tfidf /= (double)ctx->GetSlop(h); 199 | 200 | return tfidf; 201 | } -------------------------------------------------------------------------------- /redisearch/9.DesignDocuments/1.GarbageCollection.md: -------------------------------------------------------------------------------- 1 | # RedisSearch中的垃圾回收 2 | 3 | ## 1.GC的需求 4 | - 删除文档并没有真正的删除他们。为了提高效率,而是在全局文档表里标记删除。 5 | - 这意味着,文档表的id不再分配给任何文档。在遍历索引时,会检查是否被标记删除。 6 | - 所有属于该文档的反向索引项是都“垃圾”。 7 | - 我们并不想在删除文档时直接删除这些索引项,因为这个操作是很耗时的,这取决于文档的大小。 8 | - 基于上诉,更新一个文档基本上就是删除它,然后用一个新的增量id再次添加它。我们不做任何,只新建索引,所以id保持增量,更新速度很快。 9 | 10 | 上诉表明,如果我们有大量的更新和删除操作,大量的反向索引将成为垃圾,——既减慢了速度,又消耗了不必要的内存。 11 | 12 | 因为我们希望优化索引,但是也不希望这项优化工作影响其他正常操作。这意味着优化或垃圾回收应该是一个后台进程,即非侵入性的。垃圾回收速度只需要在足够长的一段时间内比删除速度快,这样就不会产生超过收集能力的垃圾。 13 | 14 | ## 2.垃圾回收一个单项倒排索引 15 | 一个单项倒排索引由一个“块”数组组成,每个块包含一个编码的记录列表——文档id增量加上其他数据,具体取决于索引编码方式。当其中的一些记录指向已删除的文档时,这部分称为“垃圾”。 16 | 17 | 算法非常简单: 18 | 19 | foreach index_block as block: 20 | 21 | reader = new_reader(block) 22 | writer = new_write(block) 23 | garbage = 0 24 | while not reader.end(): 25 | record = reader.decode_next() 26 | if record.is_valid(): 27 | if garbage != 0: 28 | # Write the record at the writer's tip with a newly calculated delta 29 | writer.write_record(record) 30 | else: 31 | writer.advance(record.length) 32 | else: 33 | garbage += record.length 34 | 35 | ### 2.1数子索引的垃圾回收 36 | 数字索引是有特殊编码的反向索引树。这意味着它可以用相同的算法,只遍历树中的每个倒排索引对象。 37 | 38 | ## 3.FORK GC 39 | 关于FORK GC的文档请参考:[blog](https://redislabs.com/blog/increased-garbage-collection-performance-redisearch-1-4-1/)。 40 | 41 | 从版本1.6开始,FORK GC已经是RedisSearc中默认的GC策略。它在清理索引的同时不降低查询和索引性能方面是非常有效的。 42 | --------------------------------------------------------------------------------