我的 Mongo 数据库中有以下文档(跳过了 _ids):
> db.names.find({})
{ "name": "John" }
{ "name": "Jack" }
{ "name": "Johny" }
{ "name": "Jenny" }
我已经为这个集合创建了 Spring Data 存储库:
public interface NameRepository extends MongoRepository<Name, ObjectId> {
Collection<Name> findByNameLike(String name);
}
结果如下:
nameRepository.findByNameLike("John"); // John, Johny
nameRepository.findByNameLike("John$"); // John
nameRepository.findByNameLike("J*ny"); // Johny, Jenny
nameRepository.findByNameLike("Jo?*ny"); // Johny, Jenny
nameRepository.findByNameLike("Jo[]]?*ny"); // empty, without error
所以它的行为就像一个智能正则表达式。现在我想自己实现这样的行为:
class MyNameRepository {
MongoOperations mongoOperations; // injected
public Collection<Name> findByName(String like) {
Query query = new Query();
query.addCriteria(Criteria.where("name").regex(like));
return mongoOperations.find(query, Name.class)
}
}
但是我的方法的行为是不同的:
myNameRepository.findByName("John"); // John, Johny
myNameRepository.findByName("John$"); // John
myNameRepository.findByName("J*ny"); // empty, without error
myNameRepository.findByName("Jo?*ny"); // error (invalid regex)
myNameRepository.findByName("Jo[]]?*ny"); // error (invalid regex)
因此,我的自定义方法的工作方式与我在 Spring 数据存储库中定义的 findByNameRegex
方法完全相同。如何实现 findByNameLike
行为?
为什么我需要这个:当我需要按许多属性过滤我的 Collection 时(例如,仅按姓名、按姓名和姓氏、按姓名和邮政编码、按姓名、姓氏和邮政编码等),我更容易支持查询作为参数,而不是在存储库中创建许多非常长的命名方法。
最佳答案
其实有个简单的方法toLikeRegex将所有 *
转换为 .*
。连同捕获无效的正则表达式,我的自定义实现可能如下所示:
class MyNameRepository {
MongoOperations mongoOperations; // injected
public Collection<Name> findByName(String like) {
try{
Query query = new Query();
query.addCriteria(Criteria.where("name").regex(toLikeRegex(like)));
return mongoOperations.find(query, Name.class);
} catch(PatternSyntaxException e) {
return Collections.emptyList();
}
}
private String toLikeRegex(String source) {
return source.replaceAll("\\*", ".*");
}
}
并且行为与 Spring Data 存储库相同。
2016 年 4 月 19 日更新
有一个MongoRegexCreator
自 1.9.0.RELEASE 起提供 toRegularExpression
方法的类。
String regex = MongoRegexCreator.INSTANCE
.toRegularExpression(userString, Part.Type.EXISTS);
关于java - Spring 如何在 mongo 中构建它的 like* 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26144251/