Эластичный поиск - нечеткость с оператором AND не работает должным образом - PullRequest
0 голосов
/ 25 октября 2018

У меня в упругом поиске ниже проиндексированных документов:

{
  "took": 10,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.9589403,
    "hits": [
      {
        "_index": "productcatalog",
        "_type": "doc",
        "_id": "1",
        "_score": 0.9589403,
        "_source": {
          "catalog_id": "343",
          "catalog_type": "series",
          "values": "Activa Rooftop, valves, VG3000, VG3000FS, butterfly, ball"
        }
      },
      {
        "_index": "productcatalog",
        "_type": "doc",
        "_id": "2",
        "_score": 0.6712582,
        "_source": {
          "catalog_id": "12717",
          "catalog_type": "product",
          "values": "Activa Rooftop, valves"
        }
      }
    ]
  }
}

Запускаю нижеприведенный API-запрос для поиска Activa Rooftop ball и ожидаю только один документ в ответ, который имеет оба Activa Rooftop ball какзначения.

GET productcatalog/_search
{
    "query": {
        "match" : {
            "values" : {
                "query" : " activa rooftp ball ",
                "operator" : "and",
                "boost": 1.0,
                "fuzziness": 2,
                "prefix_length": 0,
                "max_expansions": 100


            }
        }
    }
}

Но я получаю оба документа в качестве ответа.

Пожалуйста, найдите мой файл сопоставления ниже:

PUT productcatalog
{  
   "settings":{  
      "analysis":{  
         "analyzer":{  
            "attr_analyzer":{  
               "type":"custom",
               "tokenizer":"letter",
               "char_filter":[  
                  "html_strip"
               ],
               "filter":[  
                  "lowercase",
                  "asciifolding",
                  "stemmer_minimal_english",
                  "stemmer_minimal_german",
                  "stemmer_minimal_french",
                  "stemmer_minimal_norwegian",
                  "stemmer_minimal_portuguese"
               ]
            }
         },
         "filter":{  
            "stemmer_minimal_english":{  
               "type":"stemmer",
               "name":"minimal_english"
            },
            "stemmer_minimal_german":{  
               "type":"stemmer",
               "name":"minimal_german"
            },
            "stemmer_minimal_french":{  
               "type":"stemmer",
               "name":"minimal_french"
            },
            "stemmer_minimal_norwegian":{  
               "type":"stemmer",
               "name":"minimal_norwegian"
            },
            "stemmer_minimal_portuguese":{  
               "type":"stemmer",
               "name":"minimal_portuguese"
            }
         }
      }
   },
   "mappings":{  
      "doc":{  
         "properties":{  
            "values":{  
               "type":"text",
               "analyzer":"attr_analyzer"
            },
            "catalog_type":{  
               "type":"text"
            },
            "catalog_id":{  
               "type":"long"
            }
         }
      }
   }
}

Использую версию 6.2.3,Также, пожалуйста, найдите мой JavaAPI-код для того же нечеткого запроса, который я использую.

 QueryBuilder qb = QueryBuilders.matchQuery("values", keyword).operator(Operator.AND).boost(1.0f).fuzziness(2).prefixLength(0).maxExpansions(100);   

1 Ответ

0 голосов
/ 27 октября 2018

Ваша проблема здесь связана со стеммерами.Я проанализировал ваш attr_analyzer анализатор.Пожалуйста, посмотрите ниже.

Первый тест:

GET index-52983383/_analyze 
{
  "analyzer": "attr_analyzer", 
  "text":     "Activa Rooftop, valves, VG3000, VG3000FS, butterfly, ball"
}

Ответ:

{
  "tokens": [
    {
      "token": "activ",
      "start_offset": 0,
      "end_offset": 6,
      "type": "word",
      "position": 0
    },
    {
      "token": "rooftop",
      "start_offset": 7,
      "end_offset": 14,
      "type": "word",
      "position": 1
    },
    {
      "token": "valv",
      "start_offset": 16,
      "end_offset": 22,
      "type": "word",
      "position": 2
    },
    {
      "token": "vg",
      "start_offset": 24,
      "end_offset": 26,
      "type": "word",
      "position": 3
    },
    {
      "token": "vg",
      "start_offset": 32,
      "end_offset": 34,
      "type": "word",
      "position": 4
    },
    {
      "token": "fs",
      "start_offset": 38,
      "end_offset": 40,
      "type": "word",
      "position": 5
    },
    {
      "token": "butterfly",
      "start_offset": 42,
      "end_offset": 51,
      "type": "word",
      "position": 6
    },
    {
      "token": "ball",
      "start_offset": 53,
      "end_offset": 57,
      "type": "word",
      "position": 7
    }
  ]
}

Второй тест:

GET index-52983383/_analyze 
{
  "analyzer": "attr_analyzer", 
  "text":     "Activa Rooftop, valves"
}

Ответ:

{
  "tokens": [
    {
      "token": "activ",
      "start_offset": 0,
      "end_offset": 6,
      "type": "word",
      "position": 0
    },
    {
      "token": "rooftop",
      "start_offset": 7,
      "end_offset": 14,
      "type": "word",
      "position": 1
    },
    {
      "token": "valv",
      "start_offset": 16,
      "end_offset": 22,
      "type": "word",
      "position": 2
    }
  ]
}

Как видите, в обоих ответах у вас есть valv токенов.Расстояние Левенштейна между valv и ball, которое у вас есть в поисковом запросе, равно 2, что в точности равно вашему fuzziness параметру.

Когда вы используете fuzziness, вам часто приходится как-то идти на компромисс,В другом случае вы будете получать аналогичные ситуации.Может быть, рассмотрим использование значения AUTO вместо 2 в качестве fuzziness?Пожалуйста, посмотрите документацию , если вы не понимаете, о чем я говорю.Другим вариантом может быть установка prefix_length как минимум на 1, поэтому первый символ всегда должен совпадать.Вам нужно провести те же тесты и решить, что будет для вас наилучшим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...