Elasticsearch:在输入值中搜索索引值的子字符串

时间:2017-01-10 14:14:06

标签: elasticsearch

我有一个在弹性搜索中搜索的特殊情况。我还深入研究了文档,tokenizer(n-gram,edge-ngram),查询等以及stackoverflow搜索,但没有结果。

背景 我有一个带有一些字符串字段的小索引(例如,名称,街道,城市,电子邮件)。

这样的查询
  

Lorem ipsum dolor坐下来,这是一种不可或缺的精神。 Aenean commodo ligula eget dolor。 Aenean massa。 Cum sociis natoque penatibus et magnis dis parturient montes,nascetur ridiculus mus。 Donec quam felis,ultricies nec,pellentesque eu,pretium quis,sem。 Nulla consequat 我的名字 quis My-Street 。 Donec pede justo,fringilla vel,aliquet nec,vulputate eget,arcu。在enim justo,rhoncus ut,imperdiet a,venenatis vitae,justo。 Nullam dictum felis eu pede mollis pretium。整数tincidunt。 Cras dapibus。 Vivamus elementum semper nisi。 Aenean vulputate eleifend tellus。 Aenean leo ligula,porttitor eu,con

我想要的是搜索 来自内部的查询中的值。

所以如果我在索引中有一个名字="我的名字"或街道=" My-Street"此条目应退回。

我能找到的最接近的帖子是Search ElasticSearch field contained in a value,但是标记器只是从索引中拆分了值,我需要更像是查询中的子字符串搜索。

谢谢和最诚挚的问候 西蒙

1 个答案:

答案 0 :(得分:0)

找到了一种可能的(但不是高性能)解决方案:

1。)为搜索分析器设置n-gram过滤器 。指数分析仪仍然是“标准”:

  • 设定:

    "analysis": {
        "filter": {
            "desc_ngram": {
                "type": "ngram",
                "min_gram": 3,
                "max_gram": 50
            }
        },
        "analyzer": {
            "search_ngram": {
                "type": "custom",
                "tokenizer": "keyword",
                "filter": [ "desc_ngram", "lowercase" ]
            }
        }
    }
    
  • 映射

    "user": {
        "properties": {
            "street": {
                "type": "string",
                "analyzer": "standard",
                "search-analyzer": "search_ngram"
            }
        }...
    }
    

2.)将输入文本拆分为小块(约47个字符)

String subtext = request.post.getText().substring(startIndex, offset);

3.。)为每个块启动弹性搜索的普通查询(以异步方式执行此操作)

        return CompletableFuture.supplyAsync(() -> {

        SearchRequestBuilder search = this.prepareSearch()
                .setQuery(QueryBuilders.queryStringQuery(textToAnalyze))
                .setSize(100);

        SearchResponse response = search.get();
        UserHit result = transformToHitFrom(response, UserHit.class);
        return result;
    }).exceptionally(e -> {
        logger.error("Error occurred while searching for user", e);
        UserHit result = new UserHit();
        return result;
    });

我还没有进行性能测试,但我希望这个解决方案比标准子串方法具有更好的性能。我们将在接下来的几天内对此进行测试。

相关问题