Не четкий поиск по массиву значений

Подскажите как оформить запрос что бы можно было сделать поиск по текстовому полю с использованием массива значений К примеру запросом

    curl -XPOST 'elk:9200/shopcategory/shopcategory/_search?pretty' -d '{
        "query": {
            "bool": {
                "must": [{            
                        "match_all": {}            
                }],
                "filter": {
            "match": {
              "name": "девочкам"
            }
                }
            }
        }
    }}'


мы можем отфильтровать все записи по фразе "девочкам" Массив можно передавать только в тип term

"term": {
 "name": ["девочкам","мальчикам" ]

}


Но term подразумевает только четкие вхождения, а нам нужно осуществить "не четкий поиск", т.е. что бы нашлись девочки, девочка, мальчик, и т.д На данный момент я просто делю массив по пробелам и заключаю фразы в кавычки по длинному предложений и делаю поиск. Вопрос в том как правильно отправить эластику массив значений для не четкого поиска по всем записям?

mapping

  'properties' => [
                    'id' => ['type' => 'long', 'index' => 'not_analyzed'],
                    'parent_id' => ['type' => 'long', 'index' => 'not_analyzed'],

                    'name' => ['type' => 'string', "index"=>"analyzed", "analyzer"=>"en_rus","fielddata"=> true],
                ]`

Для нечеткого поиска надо индексировать со стемером (например kstem), а для поиска надо применять какой-нибудь запрос поддерживающий анализ, например match. Чтобы искать по нескольким словам, можно эти слова добавить в один match или объединить несколько запросов match в один запрос bool.

Для не четкого поиска я использую match
'fuzziness' => 'auto',
'prefix_length' => 3,
Все отлично ищется.
Но для того что бы отправить все запросы из массива, я объединяю кейворды в строку. Хотелось бы отправить все запросы массивом без лишних манипуляций.

без лишних манипуляций не получиться

Другой вопрос.
Можно ли получить в ответе, статистику по совпадениям слова? Документы и сколько раз встретилось совпадение?
Т.е если мы искали слово "женщинам мужчинам детям"
то получаем ответ
женщинам 1
мужчинам 2
детям 1
?

Что вы потом будете с этими ответами делать?

Мне нужно посчитать вхождения и определить релевантность длинного фразы. А точнее ветки каталога категорий

Проблема в следующем - информация по частоте совпадений во время поиска имеется. Однако, после того, как релевантность записи во время поиска рассчитана, эта информация больше не доступна. Все что мы можем сохранить это _score. Поэтому единственный способ вытащить эту информацию наружу - это путем рассчета _score на ее основе. Для этого в elasticsearch много средств.

Столкнулся с такой проблемой.
В анализируемом контенте часто встречаются слова "уход" и все производные к этому слову, а также "ухо" в разных формах
"Лекарства для глаз и ушей" и т.д, я использую не четкий поиск
'fuzziness' => 'auto',
'prefix_length' => 3,

При поиске слова "уход", в результат попадают документы содержащие "ухо", "уши" , "ушить", "уход."
Тоже самое и в обратном направлении когда ищем слово "ухо".
Как можно задать исключение, для того что бы эластик считал что слово ухо, уход, ушить это разные слова ?

Погряз я в эластике, чем глубже тем запутанней. В начале казалось все просто.
Подскажите как заставить эластик считать "Женщинам" "Женская"
совпадением без использования словаря синонимов?
с разными настройками запроса
"fuzziness": "auto",
"prefix_length" : 2
не получается.

Имеет запись
name = Женская обувь
id = 2029

Отправляю запрос

      "query": {
        "bool": {
          "must": [
            { "match": { 
    			"name": {
    				"query":     "женщинам",
    				"fuzziness": "auto",
    				"prefix_length" : 2        
    			}
    		}
    	  },        
    	  { "terms": { "id" : ["2029"]}}
          ]
        }
      }

Ответ ПУСТО!
Отправляю запрос

      "query": {
        "bool": {
          "must": [
            { "match": { 
    			"name": {
    				"query":     "женская",
    				"fuzziness": "auto",
    				"prefix_length" : 2        
    			}
    		}
    	  },        
    	  { "terms": { "id" : ["2029"]}}
          ]
        }
      }

Ответ

"hits" : [
  {
    "_index" : "shopcategory",
    "_type" : "shopcategory",
    "_id" : "2029",
    "_score" : 6.8748565,
    "_source" : {
      "id" : 2029,
      "parent_id" : 1986,
      "name" : "Женская обувь"
    }
  }

Настройки индекса такие

      'settings' => [
                'index' => ['refresh_interval' => '1s'],
                'analysis' => [
                    'filter' => [
                        'stopwords_ru' => [
                            'type' => 'stop',
                            'stopwords' => ['для','Для','от','из','со','на','по','за','до','них','все','под','другое','другие','другой','другая','товары','группа',],
                            'ignore_case' => 'true',
                        ],
                        'my_synonym_filter' => [
                            'type' => 'synonym',
                            'synonyms' =>  [
                                'женщинам, женская',                                
                            ],
                            'ignore_case' => 'true',
                        ],
                        'russian_stop' => [
                            'type' => 'stop',
                            'stopwords' => '_russian_',
                        ],
                        'russian_keywords' => [
                            'type' => 'keyword_marker',
                            'keywords' => ["пример"],
                        ],
                        'russian_stemmer' => [
                            'type' => 'stemmer',
                            'language' => 'russian',
                            //'language' => 'russian_morphology',
                        ],
                        'english_stemmer' => [
                            'type' => 'stemmer',
                            'language' => 'english',
                        ],
                    ],
                    'analyzer' => [
                        'en_rus' => [
                            'type' => 'custom',
                            'tokenizer' => 'standard',
                            'filter' => [
                                'lowercase',
                                'russian_morphology',
                                'my_synonym_filter',
                                'russian_stemmer',
                                'english_stemmer',
                                'russian_stop',
                                'my_synonym_filter',
                                'stopwords_ru',
                            ]
                        ]
                    ]
                ],
            ],

Почему эластик не показывает совпадение при запросе Женщинам и id 2029?

Без mapping- а для поля name сказать сложно. А зачем вы два русских стеммера добавили?

Проблема решилась, модуль russian_morphology не корректно работает, отключили его.

Два стеммера для одного и того же языка работать одновременно не могут.

да все верно но при одном russian_morphology результаты теже. Вырубили и все заработало

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.