领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多MongoDB 自 2.6 版本起正式提供全文搜索功能。该功能位列服务器组件 投票最多的前 5 名 功能之一,其当前版本包含众多词干分析器和解析器、短语匹配、否定和每个字段的权重。因此,是时候关注一下 Spring Data 为了支持该功能而在厨房里烹制的东西了。
对于文本索引和搜索,MongoDB 默认将语言设置为英语,通过分词、去除常用停用词和将单词还原为其基本形式来规范化文本。它也支持其他多种语言。
@Document
class CookingRecipe {
String title;
String content;
}
这里我们有一个非常简单的实体 CookingRecipe
,并希望基于其 title
和 content
字段建立文本索引,并将 title
中的搜索命中赋予 2 的权重。将权重附加到字段允许您在查找文档时影响其相关性。它定义了字段相对于其他字段的重要性,从而提高文档的分数。在本例中,当在 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 中发布的最新功能。