文本索引¶
2.4 新版功能.
MongoDB提供 文本 索引以支持对文档中字符串内容的文本搜索。
MongoDB中 文本 索引可以是任意键,只要它存储的值是字符串或者字符串数组。需要查询 文本 索引键时,使用 $text 操作符。
在 2.6 版更改: MongoDB默认启用了文本搜索特性。在MongoDB版本2.4里,您需要创建 文本 索引并执行 文本搜索 来手动启用文本搜索特性。
创建文本搜索¶
请使用 db.collection.ensureIndex() 方法创建 文本 索引。为了索引一个存储字符串或者字符串数组的键,您需要在创建选项中包含这个键并指定为 "text" ,如下:
db.reviews.ensureIndex( { comments: "text" } )
一个集合最多只能创建 一个 文本 索引。
如果希望了解在多个键上创建 文本 索引,参见 创建 文本 索引 。
支持的语言和停止词(Stop Words, 信息检索术语)¶
MongoDB支持多种语言的文本搜索。 文本 索引会去掉语言相关的停止词(例如在英语中 “the”, “an”, “a”, “and” 等等),并根据语言简单地去除后缀。如果要了解支持的语言列表,请参见 文本搜索语言 。
如果您镜语言指定为 "none" ,那么 text index 会使用简单的切词法,不会去掉停止词,也不会取词根处理。
如果索引语言是英语, 那么 文本 索引对于非附加符号(non-diacritics)大小写不敏感, 例如对于 [A-z] 大小写不敏感。
如果希望为 文本 索引指定语言, 参见 指定文本索引的语言 。
稀疏 属性¶
默认情况下, 文本 索引是 稀疏 的,并且忽略 sparse: true 选项。如果一篇文档中不包含 文本 索引键(或者这个键存储的是 null 或者空数组),那么MongoDB将不会为这篇文档建立 文本 索引项。如果是一个插入操作,MongoDB会插入这篇文档,但不把它加到 文本 索引中。
在一个复合索引中,如果同时包含了 文本 索引键和其他类型的键, 那么只有 文本索引 键可以决定索引是否要引用一篇文档。其他键无法决定是否要索引这篇文档。
限制¶
复合索引¶
MongoDB中 复合索引 可以包含一个 文本 索引键,和其它递增/递减索引键。但是,这些复合索引都有如下限制:
复合 文本 索引不能包含任何其他特殊类型索引,比如 多键索引 or 地理索引 键。
如果复合 文本 索引中有其他键排在 文本 索引键 之前 ,当查询 $text 时,这条查询必须包含对这些键的 相等匹配条件 。
参见 限制被扫描项的数量.
删除文本索引¶
如果需要删除一个 文本 索引,将索引的名字传给 db.collection.dropIndex() 方法。可以通过 getIndexes() 方法得到索引的名字。
参见 为 文本 索引指定名称 来了解有关 文本 索引的默认命名方案,以及如何避免覆盖默认名字。
存储要求和性能代价¶
对于 文本 索引,有如下存储要求和性能代价:
MongoDB中 文本 索引创建以后会将集合中接下来的记录的空间分配方式更改为 usePowerOf2Sizes 。
MongoDB中 ``文本``索引可能会很大。它们会为每篇被插入文档中被索引键的每个唯一的词根(post-stemmed word)创建索引项。
创建 文本 索引和创建一个大的多键索引很像,并且对于索引同样的数据,所需时间也会长于创建一个简单的有序(非地理)索引。
当在一个已经存在的集合上创建一个大的 文本 索引,请确保您有足够高的文件描述符打开个数的限制。参见 推荐设置 。
MongoDB中 文本 索引会影响插入,因为MOngoDB必须为每个新插入的文档中的每个被索引键的数据中的每个唯一词根添加索引项。
此外, 文本 索引不会存储词组或者文档中词的近义词的信息。所以,当整个集合可以容纳在内存中时,词组查询会比较高效。
文本搜索¶
文本搜索支持对文档中的字符串内容进行搜索。MongoDB提供 $text 操作符来执行文本搜索,对于查询和 聚集管道 都是可用的。
文本搜索过程如下:
在索引创建阶段和文本查询阶段,都需要切分单词并取出词根。
如果一篇文档的被索引键中包含了搜索词,则为它赋予一个分数。这个分数决定了一篇文档和一个给定搜索查询的相关性。
操作符 $text 可以搜索单层和词组。当整个词根被匹配上时,查询才算匹配上。例如,如果一篇文档的键包含了词 blueberry ,如果搜索的是 blue 将不会匹配上。相反,如果查询的是 blueberry 或者 blueberries 将会得到匹配。
参见 $text 操作符来了解更多文本搜索模式的信息和示例。也可以参见 在聚合管道中使用文本搜索 来了解在聚集管道上的文本搜索示例。