使用 objectify 在实体中搜索子字符串
Posted
技术标签:
【中文标题】使用 objectify 在实体中搜索子字符串【英文标题】:Search for substring within an entity using objectify 【发布时间】:2011-10-24 06:54:10 【问题描述】:我有一个名为 lastName 的实体,其值为“Benjamin”。如果用户输入“Ben”或“jam”或“Benja”,有没有办法客观化。我仍然可以使用 query.filter() 找到这个实体。我必须使用查询,因为我正在检查其他搜索条件。
我在“Obgaektify”中看到了一个名为“starts with”的运算符。但它不工作。任何建议,将不胜感激。谢谢
【问题讨论】:
为什么要在名称中进行子字符串搜索?我从来没有见过一个好的用例。 它实际上不在名称之内。它通常在文本搜索中。但为简单起见,我只是说名字:) 好吧,问题仍然存在。全文搜索会进行词干提取和规范化,然后搜索整个单词,因为查询 'cat' return 'defecate' 没有什么意义。 现在需求改变了,我只需要检查它是否以给定的文本开头。就像“benjamin”以“ben”而不是“jam”或其他任何东西开头。所以我会尝试下面发布的解决方案并查看结果。感谢您的帮助 【参考方案1】:子字符串没有“LIKE”类型的查询,但是可以通过利用索引上的>
和<
运算符来模拟区分大小写“开头为”。
// 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”开头且小于 "Ben\ufffd"
的项目,其中 \ufffd
是可能的最高 unicode 字符。
【讨论】:
`u'\ufffd' 是此处使用的规范“最大 UTF 字符”。 Cool Shady,勾选绿色勾号接受答案,这会给你 2rep,代表答案所有者并向其他人表明问题已解决。【参考方案2】:对于类似包含的查询没有标准的现有索引。顺便说一句,你总是可以介绍你自己的。在这种情况下,您可以这样做:
-
添加和合成字段如
String[] lastNameIndex
添加标记为@PrePersist
的方法,该方法将使用所有可用组合填充lastNameIndex
字段
当您想使用该索引查找实体时,请执行query.filter('lastNameIndex =', val)
【讨论】:
【参考方案3】:将 Chris 的答案和 Nick 的评论放在一起,这是为 objectify V4 构建查询过滤器的代码:
public <T> Query<T> fieldStartsWith(Query<T> query, String field, String search)
query = query.filter(field + " >=", search);
return query.filter(field + " <", searchStr+"\ufffd");
【讨论】:
我认为应该是< "\ufffd"
而不是 <=
因为 FFFD 不是可打印的 ascii 字符,因此您需要排除它。但在实践中,这可能并不重要。如果我错了,请纠正我。
谢谢奥利弗,你是对的。我修改了答案!【参考方案4】:
我使用了标记化方法。这是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。
【讨论】:
以上是关于使用 objectify 在实体中搜索子字符串的主要内容,如果未能解决你的问题,请参考以下文章