如何将Spring Data MongoDB Query与全文搜索结合起来?

时间:2014-08-28 14:05:35

标签: search full-text-search spring-data-mongodb

我最近升级到Spring Data MongoDB 1.6.0.RC1,这非常好,并实现了MongoDB 2.6(huuurah!)的全文搜索功能。我的问题是:我如何组合Criteria和TextCriteria类来生成复杂的查询?

示例对象模型:

{
  textProperty: "a text that is indexed for full text search",
  language:"en",
  aBooleanProperty: true,
  anIntegerProperty: 1
}

查询:

db.collection({ anIntegerProperty: 1,  $text: { $search: "indexed", $language: "en" } })

那么,如何使用Spring Data MongoDB类编写上述查询?

5 个答案:

答案 0 :(得分:6)

注意:此帖子之前有非工作代码,但现在已修复!

TextCriteriaCriteriaDefinition,因此可以与Query一起使用,如下所示:

Quer query = Query.query(
  Criteria.where("aBooleanProperty").is(true).
  and(anIntegerProperty).is(1)).
  addCriteria(TextCriteria.
    forLanguage("en"). // effectively the same as forDefaultLanguage() here
    matching("a text that is indexed for full text search")));

List<YourDocumentType> result = mongoTemplate.findAll(query. YourDocumentType.class);

使用Query.queryCriteria.where的静态导入进行修改,并且读起来非常流畅。

答案 1 :(得分:3)

Spring数据支持MongoDB全文搜索查询。 请考虑在下面的示例中,我们尝试在textProperty字段中搜索文本。您需要为要搜索的字段添加@TextIndexed注释。

模型对象:

public class TextExample {

@Id
private String id;

private String textProperty;

@TextIndexed
private String language;

private String aBooleanProperty;

private int anIntegerProperty;  

}

在构建TextCriteria时,您可以提供语言选项(我考虑过英语的默认语言)

查询:

TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny(
            "en");

    Query query = TextQuery.queryText(criteria).sortByScore();
    query.addCriteria(Criteria.where("anIntegerProperty").is(1));   

    List<TextExample> textExamples = mongoTemplate.find(query, TextExample.class);

这应该使用“en”和anIntegerProperty作为1的语言返回匹配记录。

有关TextCriteria文档,请参阅link

答案 2 :(得分:1)

根据我的研究TextCriteria和Criteria,无法使用Spring Data MongoDB 1.6.2.RELEASE进行聚合(group by - aggregate功能)。 我为此做了这个丑陋的黑客攻击:

private static class QueryHack extends Query implements CriteriaDefinition {
    @Override
    public DBObject getCriteriaObject() {
        return getQueryObject();
    }

    @Override
    public String getKey() {
        return null;
    }
}

然后:

QueryHack hack = new QueryHack();
hack.addCriteria(textCriteria).addCriteria(criteria);
MatchOperation match1 = new MatchOperation(hack); //Also it's not possible to use static method match(textCriteria) - it takes Criteria only. 

我将向Spring MongoDB项目添加JIRA票证。

答案 3 :(得分:0)

构建查询实体,您可以使用接受Query.addCriteria()参数的方法CriteriaDefinition来组合条件。 TextCriteriaCriteria都实施CriteriaDefinition。 例如,如果要合并TextCriteriaCriteria,可以按以下方式进行:

// Create TextCriteria
TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny("some key word"); 
// Build Query
Query query = TextQuery.queryText(criteria);
// Add the additional criteria to query
query.addCriteria(Criteria.where("field").is("fieldValue"));

答案 4 :(得分:0)

您可以使用Spring Data MongoDB创建复合索引,如下所示:

@Document
@CompoundIndex(def = "{'anIntegerProperty': 1, 'textProperty': 'text'}")

然后创建一个存储库:

@Repository
public interface TheDocuemntRepository extends MongoRepository<TheDocuemnt, String> {

    Stream<TheDocuemnt> findByAnIntegerPropertyOrderByScoreDesc(Integer anIntegerProperty, TextCriteria criteria);

}

考虑MongoDB文档:

  

复合指数

     

复合索引可以包括文本索引键以及升序/降序索引键。但是,这些复合索引具有以下限制:

     
      
  • 复合文本索引不能包含任何其他特殊索引类型,例如多键或地理空间索引字段。

  •   
  • 如果复合文本索引包含文本索引键之前的键,要执行$ text搜索,查询谓词必须在前面的键上包含相等匹配条件。

  •   

按语言过滤搜索结果

如果您还想按语言过滤搜索结果,则应尝试以下方法:Multi-language documents example

实体

@CompoundIndex(def = "{'anIntegerProperty': 1, 'language': 1, 'textProperty': 'text'}")

存储库

Sort TEXT_SCORE_SORT = new Sort(Direction.DESC, "score");

@Query("{'anIntegerProperty': ?0, 'language': ?1, $text: {$search: ?2, $language: ?1}}")
Stream<TheDocuemnt> findTheDocument(Integer property, String language, String criteria, Sort sort);