【问题标题】:Spring data mongodb: Text search for 'phrase OR words in phrase'Spring data mongodb:文本搜索“短语或短语中的单词”
【发布时间】:2015-08-28 09:19:53
【问题描述】:

我需要在名为 blog 的集合中搜索文档,该集合具有为标题、标签、摘要和正文定义的文本索引:

@Document(collection="blog")
public class Blog {
    @Id
    private String id;
    @TextIndexed(weight = 10)
    private String title;
    @TextIndexed(weight = 9)
    private String tags;
    @TextIndexed(weight = 8)
    private String summary;
    @TextIndexed(weight = 7)
    private String body;
    @TextScore
    private Float score;

    //getters and setters
}

现在,我需要根据以下条件对 blog 集合执行文本搜索:

  1. 检查用户输入是否包含多个单词。
  2. 如果 searchKey 是单个词,则执行文本搜索并根据权重返回排序后的响应。
  3. 如果 searchKey 包含多个单词,则搜索完整的 PHRASE 或 PHRASE 中的任何单词。

对于第二种情况,TextCriteria 定义如下:

TextCriteria criteria = TextCriteria.forDefaultLanguage().matching("SingleWord");

对于第三种情况,如何在单个查询中为组合编写条件定义:

query 1: db.articles.find( { $text: { $search: "\"coffee cake\"" } } ) //phrase search
query 2: db.articles.find( { $text: { $search: "coffee cake" } } ) //word search

我可以用

进行搜索吗
query 1 OR query 2 with sorted result based on score.

匹配完整短语的结果得分应该更高。

【问题讨论】:

  • 你能找到任何解决方案吗?

标签: java mongodb spring-data-mongodb


【解决方案1】:

Spring Data MongoDB 支持以下文本搜索操作:

  • TextCriteria.forDefaultLanguage().matchingAny("search term1", "search term2")
  • TextCriteria.forDefaultLanguage().matching("search term")
  • TextCriteria.forDefaultLanguage().matchingPhrase("search term")

第一个条件可以执行文本搜索:search、text1 和 text2 第二个条件可以执行文本搜索:搜索、词条 第三个条件是词组搜索:'search term'

可以使用上述条件形成文本查询:

Query query = TextQuery.queryText(TextCriteria.forDefaultLanguage().matchingAny("search term").sortByScore().with(new PageRequest(pageNum, docCount, new Sort(new Order(Sort.Direction.DESC, "score"))));

要使用分数(文本搜索分数)进行排序,我们需要在相应的 POJO 中添加一个名为 score 的字段:

@TextScore
private Float score;

我们可以在文本查询中添加其他过滤器,如下所示:

query.addCriteria(Criteria.where("city").is("Delhi").and("country").is("India").and("price").lte(200.50).gte(100.50);

最后执行这个查询:

List<Product> products = mongoOperations.find(query, Product.class)

默认情况下,Mongodb 会为短语匹配分配更高的分数。因此,在需要更高分数的短语匹配然后正常文本匹配的情况下,不需要先找到短语匹配。

【讨论】:

【解决方案2】:

MongoRepository 还支持对全文文档的 TextCriteria 查询。它被描述为here

@Document
class FullTextDocument {

  @Id String id;
  @TextIndexed String title;
  @TextIndexed String content;
  @TextScore Float score;
}

interface FullTextRepository extends Repository<FullTextDocument, String> {

  // Execute a full-text search and define sorting dynamically
  List<FullTextDocument> findAllBy(TextCriteria criteria, Sort sort);

  // Paginate over a full-text search result
  Page<FullTextDocument> findAllBy(TextCriteria criteria, Pageable pageable);

  // Combine a derived query with a full-text search
  List<FullTextDocument> findByTitleOrderByScoreDesc(String title, TextCriteria criteria);
}

Sort sort = Sort.by("score");
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny("spring", "data");
List<FullTextDocument> result = repository.findAllBy(criteria, sort);

criteria = TextCriteria.forDefaultLanguage().matching("film");
Page<FullTextDocument> page = repository.findAllBy(criteria, PageRequest.of(1, 1, sort));
List<FullTextDocument> result = repository.findByTitleOrderByScoreDesc("mongodb", criteria);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多