2011-08-10 20 views
10

我有一个名为lastName的实体,其值为“Benjamin”。如果用户放置“Ben”或“jam”或“Benja”,是否有物化的方法?我仍然可以使用query.filter()找到这个实体。我必须使用查询,因为有其他搜索条件我正在检查。使用对象化在实体中搜索子串

我在“Obgaektify”中看到了一些名为“开始于”的操作符。但它不工作。任何建议,将不胜感激。谢谢

+1

你为什么要在名称中进行子字符串搜索?我从来没有见过这样的好用例。 –

+0

它不在名称内。它一般在文本搜索范围内。但为了简单,我只是说名称:) –

+3

嗯,问题依然存在。全文搜索可以进行词干化和规范化,然后搜索整个单词,因为对'猫'的查询返回'大便'没有意义。 –

回答

12

对子字符串没有“LIKE”类型的查询,但是区分大小写“开始于”可以通过采用优势e的><运营商的索引。

// The start string 
String searchStr = "Ben"; 

// emulate a "starts with" query 
Query q = new Query("MyEntity") 
q.addFilter("name", Query.FilterOperator.GREATER_THAN_OR_EQUAL, searchStr); 
q.addFilter("name", Query.FilterOperator.LESS_THAN, searchStr + "\ufffd"); 

查询将“搜索”的name属性与“本”开头的项目,小于"Ben\ufffd",其中\ufffd是尽可能高的Unicode字符。

+0

'u'\ ufffd'是这里使用的规范的'最大的UTF字符'。 –

+0

这对我有用。感谢您的帮助:) –

+0

酷阴影,通过勾选绿色勾号接受答案,这会让您2rep,代表答案所有者并向其他人表明问题已解决。 –

2

对包含式查询没有标准的现有索引。顺便说一句,你可以随时引入你自己的。在这种情况下,你可以这样做:

  1. 添加和合成领域像标记为@PrePersistString[] lastNameIndex
  2. add方法,将填补lastNameIndex场与所有可用的组合
  3. 当你想使用这个指数做query.filter('lastNameIndex =', val)找到实体
0

把从克里斯的答案,从尼克一起评论,这里是建立一个查询筛选客观化V4代码:

public <T> Query<T> fieldStartsWith(Query<T> query, String field, String search){ 
    query = query.filter(field + " >=", search); 
    return query.filter(field + " <", searchStr+"\ufffd"); 
} 
+0

我相信应该是'<“\ ufffd”'而不是'<=',因为FFFD不是可打印的ascii字符,所以你想排除它。但实际上它可能并不重要。如我错了请纠正我。 –

+0

谢谢奥利弗,你是对的。我修改了我的答案! – Zensursula

0

我已经使用了符号化方法。这里是Java中的代码:

private String tokenize(String phrase) { 
StringBuilder tokens = new StringBuilder(); 
try { 
    for (String word : phrase.split(" ")) { 
    if (word.length() < 1) { 
     continue; 
    } 
    int j = 1; 
    while (true) { 
     for (int i = 0; i < word.length() - j + 1; i++) { 
     tokens.append(word.substring(i, i + j)).append(" "); 
     } 
     if (j == word.length()) { 
     break; 
     } 
     j++; 
    } 
    } 
} catch (Throwable t) { 
    t.printStackTrace(); 
} 
return tokens.toString();} 

这允许定义一个可索引字段,然后处理标准的Ofy查询和SearchService。