2014-10-01 60 views
3

我在Mongo的數據庫中的以下文件(_ids跳過):Spring如何在mongo中構建它的*查詢?

> db.names.find({}) 
{ "name": "John" } 
{ "name": "Jack" } 
{ "name": "Johny" } 
{ "name": "Jenny" } 

我已經創造了這個系列的春數據倉庫:

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) 

所以我的自定義方法的工作原理完全一樣我會在春天的數據倉庫定義findByNameRegex方法。如何實施findByNameLike行爲?

爲什麼我需要這個:當我需要通過許多屬性(例如,按名稱,姓名,姓名和郵政編碼,姓名,郵政編碼等等)過濾我的收藏時,我更容易支持將查詢作爲參數,而不是在存儲庫中創建許多超長命名的方法。

回答

1

實際上,有一個簡單的方法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("\\*", ".*"); 
    } 
} 

,並表現爲春季數據倉庫做了同樣的。


更新2016年4月19日

有自1.9.0.RELEASE,提供了一個toRegularExpression方法的MongoRegexCreator類。

String regex = MongoRegexCreator.INSTANCE 
       .toRegularExpression(userString, Part.Type.EXISTS);