我最近升级到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类编写上述查询?
答案 0 :(得分:6)
注意:此帖子之前有非工作代码,但现在已修复!
TextCriteria
是CriteriaDefinition
,因此可以与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.query
和Criteria.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
来组合条件。 TextCriteria
和Criteria
都实施CriteriaDefinition
。
例如,如果要合并TextCriteria
和Criteria
,可以按以下方式进行:
// 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);