GAE数据存储区(Java)中的部分文本搜索

时间:2014-02-03 09:02:28

标签: java google-app-engine google-cloud-datastore

我正在尝试查询我的(GAE Java)数据存储区的文本字段并期望包含部分匹配的结果。例如,搜索字符串“test”的结果应包括“test,test1,more tests等”。下面是我正在使用的Java代码片段。

        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        Filter testFilter = new FilterPredicate("test", FilterOperator.GREATER_THAN_OR_EQUAL, testStr);
        Query testQuery = new Query("testEntity").setFilter(testFilter);
        List<Entity> testResults = datastore.prepare(testQuery).asList(FetchOptions.Builder.withLimit(100));

我的测试结果完全无关紧要。我是GAE和Java的新手,我相信我没有走上正轨。我在SO和其他网站上搜索了正确的方法,并找到了Python的解决方案,但找不到任何Java。我遇到的Java示例都使用带有整数值的查询。请建议。

2 个答案:

答案 0 :(得分:3)

我的例子是按名称搜索我的应用程序的用户。我为每个用户创建了一个文档,该文档包含您可以搜索的每个可能的字符串。

例如,用户“John Smith”的文档有一个字符串:由空格分隔的搜索输入:“joh ohn smi smit mith(etc)”。

这里是我用来使这个工作的代码。 “id”是我的后端数据存储区中用户的ID。

private void createSearchableUserDoc(String id, String displayName) {
    List<String> substrings = buildAllSubstrings(displayName);
    String combinedString = combine(substrings, " ");
    // The input for this looks like "CHR CHRI CHRIS HRI HRIS" etc...
    createUserDocument(id, combinedString);
}

private List<String> buildAllSubstrings(String displayName) {
    List<String> substrings = new ArrayList<String>();
    for (String word : displayName.split(" ")) {
        int wordSize = 1;
        while (true) {
            for (int i = 0; i < word.length() - wordSize + 1; i++) {
                substrings.add(word.substring(i, i + wordSize));
            }
            if (wordSize == word.length())
                break;
            wordSize++;
        }
    }
    return substrings;
}

private String combine(List<String> strings, String glue) {
    int k = strings.size();
    if (k == 0)
        return null;
    StringBuilder out = new StringBuilder();
    out.append(strings.get(0));
    for (int x = 1; x < k; ++x)
        out.append(glue).append(strings.get(x));
    return out.toString();
}

private void createUserDocument(String id, String searchableSubstring) {
    Builder docBuilder = Document
            .newBuilder()
            .setId(id)
            .addField(
                    Field.newBuilder().setName("Display_Name")
                            .setText(searchableSubstring));

    addDocToIndex(docBuilder.build());

}

private void addDocToIndex(Document document) {

    Index index = getUserDocIndex();

    try {
        index.put(document);
    } catch (PutException e) {
        log.severe("Error putting document in index... trying again.");
        if (StatusCode.TRANSIENT_ERROR.equals(e.getOperationResult().getCode())) {
            index.put(document);
        }
    }
}

public static Index getUserDocIndex() {
    IndexSpec indexSpec = IndexSpec.newBuilder().setName("USER_DOC_INDEX").build();
    Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);
    return index;
}

要执行搜索,我执行了此操作:

    Query query = Query.newBuilder().build("Display_Name" + "=" + searchText);

    Index userDocIndex = getUserDocIndex();
    Results<ScoredDocument> matchingUsers = userDocIndex.search(query);

答案 1 :(得分:2)

如果要进行文本搜索,请使用GAE全文搜索

https://developers.google.com/appengine/docs/java/search/