抢先一步
VMware 提供培训和认证,以加速您的进步。
了解更多自 2.6 版本以来,MongoDB 官方提供了全文搜索功能。该功能在服务器组件中排名 前 5 名 最受投票的功能,并且当前版本带有许多词干提取器和解析器、短语匹配、否定和每个字段的权重。 所以现在是时候给它一些关注,并分享 Spring Data 厨房中正在烹饪的内容以支持该功能。
对于文本索引和搜索,MongoDB 默认将语言设置为英语,通过标记化、删除常见的停用词并将单词简化为基本形式来规范化文本。 它还支持其他几种语言。
@Document
class CookingRecipe {
String title;
String content;
}
这里我们有一个非常简单的实体 CookingRecipe
,并且想要基于其 title
和 content
字段构建文本索引,并将权重 2 赋予 title
中的搜索命中。 将权重附加到字段允许您影响文档在查找时的相关性。 它定义了字段相对于其他字段的重要性,从而提高了文档的分数。 在这种情况下,如果 title
中命中匹配项,则文档的相关性会加倍。 原始 MongoDB 索引定义如下所示
{
title : "text",
content : "text"
},
{
weights: { title : 2 }
}
从 Spring Data MongoDB 的 1.5 M1 版本开始,我们可以手动创建一个文本索引,捕获我们想要启用全文搜索的字段。
TextIndexDefinition textIndex = new TextIndexDefinitionBuilder()
.onField("title", 2F)
.onField("content")
.build();
MongoTemplate template = … // obtain MongoTemplate
template.indexOps(CookingRecipe.class).ensureIndex(textIndex);
或者,让索引使用映射注解自动创建。 我们所需要做的就是在域类上添加一些提示,我们就可以开始了。
@Document
class CookingRecipe {
@TextIndexed(weight=2) String title;
@TextIndexed String content;
}
请注意,每个集合只能有一个全文索引。 现在我们已经创建了索引,我们将查询与“coffee”或“cake”匹配的前 5 个食谱。
TextCriteria criteria = TextCriteria.forDefaultLanguage()
.matchingAny("coffee", "cake");
Query query = TextQuery.queryText(criteria)
.sortByScore()
.with(new PageRequest(0, 5));
List<CookingRecipe> recipes = template.find(query, CookingRecipe);
请注意,我们提供了专用的类型 TextCriteria
和 TextQuery
来详细表达搜索。
如前所述,文档在搜索时会进行评分。 score
值默认不返回,但由于此信息通常很有用,我们可以通过将 { score : { $meta : "textScore" } }
添加到投影中来将其包含在输出中,这可以通过调用 query.sortByScore()
隐式完成。 要访问结果文档中的分数,我们在 CookingRecipe
中添加一个 @TextScore
注解的属性。
@Document
class CookingRecipe {
@TextIndexed(weight=2) String title;
@TextIndexed String content;
@TextScore Float score;
}
由于 @TextScore
注解本身带有 @ReadOnlyProperty
注解,因此它隐式地将 score
属性转换为只读属性。 后者也可以在其他上下文中使用,如果您想确保文档中的字段只能读取而永远不能写入。
有关 行为和限制 以及 支持的语言 的其他资源可以在 MongoDB 参考 中找到。
随着发布周期 Evans 的推进,我们将向 MongoRepositories
添加文本搜索支持。
如果您想了解有关 Spring Data 的更多信息,请务必 注册 今年的 SpringOne 会议。 时间表 包含许多与数据相关的演讲,向您介绍我们将随 Evans 一起提供的最新功能。