【问题标题】:ElasticSearch - JavaApi searching by each character instead of term (word)ElasticSearch - JavaApi 按每个字符而不是术语(单词)搜索
【发布时间】:2018-07-07 11:52:09
【问题描述】:

我正在使用 java api 从弹性搜索中获取文档,我的弹性搜索文档中有以下 code,并尝试使用以下模式进行搜索。

code : MS-VMA1615-0D

Input : MS-VMA1615-0D   -- Am getting the results (MS-VMA1615-0D).
Input : VMA1615         -- Am getting the results (MS-VMA1615-0D) .
Input : VMA             -- Am getting the results (MS-VMA1615-0D) .

但是,如果我像下面这样输入,我不会得到结果。

Input : V       -- Am not getting the results.
INPUT : MS      -- Am not getting the results.
INPUT : -V      -- Am not getting the results.
INPUT : 615     -- Am not getting the results.

我期待返回代码 MS-VMA1615-0D。简单来说,我尝试逐个字符而不是词条(单词)来搜索。

对于以下情况,它不应该返回代码MS-VMA1615-0D,因为它与我的代码不匹配。

Input : VK      -- should not return the results.
INPUT : MS3     -- should not return the results.

请在下面找到我正在使用的 java 代码

private final String INDEX = "products";
private final String TYPE = "doc";
SearchRequest searchRequest = new SearchRequest(INDEX); 
    searchRequest.types(TYPE);
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    QueryStringQueryBuilder qsQueryBuilder = new QueryStringQueryBuilder(code); 

    qsQueryBuilder.defaultField("code");
    searchSourceBuilder.query(qsQueryBuilder);

    searchSourceBuilder.size(50);
    searchRequest.source(searchSourceBuilder);
    SearchResponse searchResponse = null;
    try {
         searchResponse = SearchEngineClient.getInstance().search(searchRequest);
    } catch (IOException e) {
        e.getLocalizedMessage();
    }
    Item item = null;
    SearchHit[] searchHits = searchResponse.getHits().getHits();

请查看我的映射详情:

PUT products
{
"settings": {
"analysis": {
  "analyzer": {
    "custom_analyzer": {
      "type": "custom",
      "tokenizer": "my_pattern_tokenizer",
      "char_filter": [
        "html_strip"
      ],
      "filter": [
        "lowercase",
        "asciifolding"
      ]
    }
   },
   "tokenizer": {
     "my_pattern_tokenizer": {
          "type": "pattern",
          "pattern": "-|\\d"
        }
   }
  }
},
"mappings": {
"doc": {
  "properties": {
    "code": {
      "type": "text",
       "analyzer": "custom_analyzer"
      }
    }
  }
 }
}

使用新答案更新后:

这是我通过 Java API 提出的请求

'SearchRequest{searchType=QUERY_THEN_FETCH, indices=[products], indicesOptions=IndicesOptions[id=38, ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false], types=[doc], routing='null', preference='null', requestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=128, source={"size":50,"query":{"match_phrase":{"code":{"query":"1615","slop":0,"boost":1.0}}}}}

' 。但我得到了null的回复

【问题讨论】:

    标签: java elasticsearch elastic-stack


    【解决方案1】:

    跟进:ElasticSearch - JavaApi searching not happening without (*) in my input query

    您的映射应如下所示:

    PUT products
    {
    "settings": {
    "analysis": {
      "analyzer": {
        "custom_analyzer": {
          "type": "custom",
          "tokenizer": "ngram",
          "char_filter": [
            "html_strip"
          ],
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
    },
    "mappings": {
    "doc": {
      "properties": {
        "code": {
          "type": "text",
           "analyzer": "custom_analyzer"
          }
        }
      }
     }
    }
    

    您应该使用 match_phrase 查询。

    在 Kibana 中:

    GET products/_search
    {
      "query": {
        "match_phrase": {
          "code": "V"
        }
      }
    }
    

    将返回结果:

    "hits": [
          {
            "_index": "products",
            "_type": "doc",
            "_id": "EoGtdGQBqdof7JidJkM_",
            "_score": 0.2876821,
            "_source": {
              "code": "MS-VMA1615-0D"
            }
          }
        ]
    

    但是这个:

    GET products/_search
    {
      "query": {
        "match_phrase": {
          "code": "VK"
        }
      }
    }
    

    不会:

    {
      "took": 10,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": 0,
        "max_score": null,
        "hits": []
      }
    }
    

    根据您的评论:

    而不是使用查询字符串:

    QueryStringQueryBuilder qsQueryBuilder = new QueryStringQueryBuilder(code); 
    qsQueryBuilder.defaultField("code");
    searchSourceBuilder.query(qsQueryBuilder);
    searchSourceBuilder.size(50);
    searchRequest.source(searchSourceBuilder);
    

    使用匹配短语查询:

    QueryBuilder query = QueryBuilders.matchPhraseQuery("code", code);
    searchSourceBuilder.query(query);
    searchSourceBuilder.size(50);
    searchRequest.source(searchSourceBuilder);
    

    【讨论】:

    • 如果我正在搜索 1615.,我也会得到这些结果 S683616161S611751561S661506173 不完全是 1615。我正在使用QueryStringQueryBuilder qsQueryBuilder = new QueryStringQueryBuilder(code); java API。
    • 更新了我的答案。
    • 我已经按照建议修改了我的代码。但是我在这条线上遇到空指针异常SearchHit[] searchHits = searchResponse.getHits().getHits();
    • @Technocrad - 我已经根据我的要求更新了我的问题,
    • 嘿,这个请求非常好,我也在 java 中尝试过,它给了我预期的结果。问题是别的,可能需要调试才能检查。
    猜你喜欢
    • 2012-09-09
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多