Не работают стоп слова


(konovalova) #1

Я использую elasticsearch php.
первоначальный маппинг выглядит так

$params = [
    'index' => 'myindex',
    'type' => 'faq_article',
    'body' => [
        'settings' => [
            'analysis' => [
                'char_filter' => [
                    'ru' => [
                        'type' => 'mapping',
                        'mappings' => ['Ё=>Е', 'ё=>е']
                    ],
                ],
                'analyzer' => [
                    'app_index_analyzer' => [
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'char_filter' => ['ru',  'html_strip'],
                        'filter' => ['lowercase', 'stop', 'russian_morphology', 'english_morphology']
                    ],
                    'app_search_analyzer' => [
                        'type' => 'custom',
                        'tokenizer' => 'standard',
                        'char_filter' => ['ru',  'html_strip'],
                        'filter' => ['lowercase', 'stop', 'russian_morphology', 'english_morphology']
                    ]
                ],
            ],
            'filter' => [
                'stop' => [
                    'type' => 'stop',
                    'stopwords' => ['как','а','без','более','бы','был','была','были','было','быть','в','вам','вас','весь','во','вот','все','всего','всех','вы','где','да','даже','для','до','его','ее','если','есть','еще','же','за','здесь','и','из','или','им','их','к','как','ко','когда','кто','ли','либо','мне','может','мы','на','надо','наш','не','него','нее','нет','ни','них','но','ну','о','об','однако','он','она','они','оно','от','очень','по','под','при','с','со','так','также','такой','там','те','тем','то','того','тоже','той','только','том','ты','у','уже','хотя','чего','чей','чем','что','чтобы','чье','чья','эта','эти','это','я','a','an','and','are','as','at','be','but','by','for','if','in','into','is','it','no','not','of','on','or','such','that','the','their','then','there','these','they','this','to','was','will','with'],
                    'ignore_case' => true
                ]
            ]
        ],
        'mapping' => [
            'faq_article' => [
                '_source' => [
                    'enabled' => true
                ],
                'properties' => [
                    'id' => [
                        'type' => 'integer'
                    ],
                    'topic' => [
                        'type' => 'integer'
                    ],
                    'question' => [
                        'index_analyzer' => 'app_index_analyzer',
                        'search_analyzer' => 'app_search_analyzer',
                        'type' => 'string'
                    ],
                    'answer' => [
                        'index_analyzer' => 'app_index_analyzer',
                        'search_analyzer' => 'app_search_analyzer',
                        'type' => 'string'
                    ],
                ]
            ]
        ]
    ]
];

индексирую документы в цикле

foreach($articlesFaq as $article){
    $params['id'] = $article->getId();
    $params['body']['id'] = $article->getId();
    $params['body']['topic'] = $article->topic->id;
    $params['body']['question'] = $article->question;
    $params['body']['answer'] = $article->answer;
    try {
        $response = $client->index($params);
        print_r($response);
    } catch (Exception $e) {
        print_r($client->transport->getLastConnection()->getLastRequestInfo());
    }
}

но когда я делаю поиск, то я получаю ответы со стоп словами
по запросу "БЕЗ" мне радостно приходит "КАК ИГРАТЬ БЕЗ"
по запросу "как" мне приходят "КАК ПОМЕНЯТЬ" и тд

Подскажите, что я сделала не так?


(Igor Motov) #2

Давайте начнем с того, что убедимся, что у вас индекс создается правильно. Запустите вот эту команду на сервере Elasticsearch, и давайте сравним установки и схему созданного индекса с установками в Вашем приложении:

curl localhost:9200/myindex

Вы не могли бы также показать, как вы осуществляете поиск?


(konovalova) #3
{
  "myindex" : {
    "aliases" : { },
    "mappings" : {
      "faq_article" : {
        "properties" : {
          "answer" : {
            "type" : "string"
          },
          "id" : {
            "type" : "string"
          },
          "mapping" : {
            "properties" : {
              "faq_article" : {
                "properties" : {
                  "_source" : {
                    "properties" : {
                      "enabled" : {
                        "type" : "boolean"
                      }
                    }
                  },
                  "properties" : {
                    "properties" : {
                      "answer" : {
                        "properties" : {
                          "index_analyzer" : {
                            "type" : "string"
                          },
                          "search_analyzer" : {
                            "type" : "string"
                          },
                          "type" : {
                            "type" : "string"
                          }
                        }
                      },
                      "id" : {
                        "properties" : {
                          "type" : {
                            "type" : "string"
                          }
                        }
                      },
                      "question" : {
                        "properties" : {
                          "index_analyzer" : {
                            "type" : "string"
                          },
                          "search_analyzer" : {
                            "type" : "string"
                          },
                          "type" : {
                            "type" : "string"
                          }
                        }
                      },
                      "topic" : {
                        "properties" : {
                          "type" : {
                            "type" : "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "question" : {
            "type" : "string"
          },
          "settings" : {
            "properties" : {
              "analysis" : {
                "properties" : {
                  "analyzer" : {
                    "properties" : {
                      "app_index_analyzer" : {
                        "properties" : {
                          "char_filter" : {
                            "type" : "string"
                          },
                          "filter" : {
                            "type" : "string"
                          },
                          "tokenizer" : {
                            "type" : "string"
                          },
                          "type" : {
                            "type" : "string"
                          }
                        }
                      },
                      "app_search_analyzer" : {
                        "properties" : {
                          "char_filter" : {
                            "type" : "string"
                          },
                          "filter" : {
                            "type" : "string"
                          },
                          "tokenizer" : {
                            "type" : "string"
                          },
                          "type" : {
                            "type" : "string"
                          }
                        }
                      }
                    }
                  },
                  "char_filter" : {
                    "properties" : {
                      "ru" : {
                        "properties" : {
                          "mappings" : {
                            "type" : "string"
                          },
                          "type" : {
                            "type" : "string"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "filter" : {
                "properties" : {
                  "stop" : {
                    "properties" : {
                      "ignore_case" : {
                        "type" : "boolean"
                      },
                      "stopwords" : {
                        "type" : "string"
                      },
                      "type" : {
                        "type" : "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "topic" : {
            "type" : "string"
          }
        }
      }
    },

(konovalova) #4
"settings" : {
      "index" : {
        "creation_date" : "1463999819039",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "XFsNE63DSB-OSE_L1Xzr0g",
        "version" : {
          "created" : "2030199"
        }
      }
    },
    "warmers" : { }
  }
}

(Igor Motov) #5

Как я и думал, создание индекса вашей командой не происходит. Индекс, скорее всего, создается автоматически с установками по умолчанию при индексации первой записи. Вам нужно, пересоздать индекс предварительно исправив параметры (filter должен быть внутри analysys в установках).


(konovalova) #6

Фильтр исправила. При обращении curl localhost:9200/myindex я вижу все по прежнему
При обращении к конкретному проиндексированному документу curl localhost:9200/myindex/faq_article/1
выдает вот это

{
  "_index" : "myindex",
  "_type" : "faq_article",
  "_id" : "1",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "settings" : {
      "analysis" : {
        "char_filter" : {
          "ru" : {
            "type" : "mapping",
            "mappings" : [ "Ё=>Е", "ё=>е" ]
          }
        },
        "analyzer" : {
          "app_index_analyzer" : {
            "type" : "custom",
            "tokenizer" : "standard",
            "char_filter" : [ "ru", "html_strip" ],
            "filter" : [ "lowercase", "stop", "russian_morphology", "english_morphology" ]
          },
          "app_search_analyzer" : {
            "type" : "custom",
            "tokenizer" : "standard",
            "char_filter" : [ "ru", "html_strip" ],
            "filter" : [ "lowercase", "stop", "russian_morphology", "english_morphology" ]
          }
        }
      },
      "filter" : {
        "stop" : {
          "type" : "stop",
          "stopwords" : "как,а,без,более,бы,был,была,были,было,быть,в,вам,вас,весь,во,вот,все,всего,всех,вы,где,да,даже,для,до,его,ее,если,есть,еще,же,за,здесь,и,из,или,им,их,к,как,ко,когда,кто,ли,либо,мне,может,мы,на,надо,наш,не,него,нее,нет,ни,них,но,ну,о,об,однако,он,она,они,оно,от,очень,по,под,при,с,со,так,также,такой,там,те,тем,то,того,тоже,той,только,том,ты,у,уже,хотя,чего,чей,чем,что,чтобы,чье,чья,эта,эти,это,я,a,an,and,are,as,at,be,but,by,for,if,in,into,is,it,no,not,of,on,or,such,that,the,their,then,there,these,they,this,to,was,will,with",
          "ignore_case" : true
        }
      }
    },
    "mapping" : {
      "faq_article" : {
        "_source" : {
          "enabled" : true
        },
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "topic" : {
            "type" : "integer"
          },
          "question" : {
            "index_analyzer" : "app_index_analyzer",
            "search_analyzer" : "app_search_analyzer",
            "type" : "string"
          },
          "answer" : {
            "index_analyzer" : "app_index_analyzer",
            "search_analyzer" : "app_search_analyzer",
            "type" : "string"
          }
        }
      }
    },
    "id" : "1",
    "topic" : "3",
    "question" : "Пополнение лицевого счета",
    "answer" : "<p style=\"box-sizing: border-box; margin: 0px 0px 10px; color: rgb(36, 42, 48); font-family: RobotoRegular, sans-serif; line-height: 18.2px; background-color: rgb(255, 255, 255);\">Какой-то текст</p>\r\n"
  }
}


(Igor Motov) #7

Судя по результату

curl localhost:9200/myindex/faq_article/1

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

$client->indices()->create($params);

После этого params надо почистить - в каждом документе они больше не нужны.


(konovalova) #8

Создала индекс через $client->indices()->create($params)

[index] => myindex
    [type] => faq_article
    [id] => 24
    [body] => Array
        (
            [id] => 24
            [topic] => 1
            [question] => как играть без аккаунта?
            [answer] => <span style="color: rgb(36, 42, 48); font-family: RobotoRegular, sans-serif; line-height: 18.2px; background-color: rgb(255, 255, 255);">/*....*/</span>
        )

проиндексировала документы через $client->index($docs)

но когда делаю поиск

 $params = [
		'index' => 'myindex',
		'type' => 'faq_article',
		'body' => [
		'query'=> array(
		'function_score'=> array(

			'query'=> array(
				'multi_match'=> array(
					'query'=> $search,
					'operator'=> 'OR',
					'fields'=> array(
						'question',
						'answer'
					)
				)
			),                     
			'functions'=> array(
			),
			'boost_mode'=> 'multiply'
		)
	)
];

$response = $client->search($params);	

все равно получаю документы со стоп - словами((((


(Igor Motov) #9

А что возвращают теперь эти две команды?

curl localhost:9200/myindex/
curl localhost:9200/myindex/faq_article/24

(konovalova) #10

curl localhost:9200/myindex/ возвращает

{
  "myindex" : {
    "aliases" : { },
    "mappings" : {
      "faq_article" : {
        "properties" : {
          "answer" : {
            "type" : "string"
          },
          "id" : {
            "type" : "string"
          },
          "question" : {
            "type" : "string"
          },
          "topic" : {
            "type" : "string"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "filter" : {
          "stop" : {
            "ignore_case" : "true",
            "type" : "stop",
            "stopwords" : [ "как", "а", "без", "более", "бы", "был", "была", "были", "было", "быть", "в", "вам", "вас", "весь", "во", "вот", "все", "всего", "всех", "вы", "где", "да", "даже", "для", "до", "его", "ее", "если", "есть", "еще", "же", "за", "здесь", "и", "из", "или", "им", "их", "к", "как", "ко", "когда", "кто", "ли", "либо", "мне", "может", "мы", "на", "надо", "наш", "не", "него", "нее", "нет", "ни", "них", "но", "ну", "о", "об", "однако", "он", "она", "они", "оно", "от", "очень", "по", "под", "при", "с", "со", "так", "также", "такой", "там", "те", "тем", "то", "того", "тоже", "той", "только", "том", "ты", "у", "уже", "хотя", "чего", "чей", "чем", "что", "чтобы", "чье", "чья", "эта", "эти", "это", "я", "a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with" ]
          }
        },
        "number_of_shards" : "5",
        "creation_date" : "1464023773416",
        "analysis" : {
          "analyzer" : {
            "app_search_analyzer" : {
              "filter" : [ "lowercase", "stop", "russian_morphology", "english_morphology" ],
              "char_filter" : [ "ru", "html_strip" ],
              "type" : "custom",
              "tokenizer" : "standard"
            },
            "app_index_analyzer" : {
              "filter" : [ "lowercase", "stop", "russian_morphology", "english_morphology" ],
              "char_filter" : [ "ru", "html_strip" ],
              "type" : "custom",
              "tokenizer" : "standard"
            }
          },
          "char_filter" : {
            "ru" : {
              "type" : "mapping",
              "mappings" : [ "Ё=>Е", "ё=>е" ]
            }
          }
        },
        "number_of_replicas" : "1",
        "uuid" : "zv7NIpnvSHyM5NaYxY6aOA",
        "version" : {
          "created" : "2030199"
        }
      }
    },
    "warmers" : { }
  }
}

curl localhost:9200/myindex/faq_article/24 возвращает

{
  "_index" : "myindex",
  "_type" : "faq_article",
  "_id" : "24",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "id" : "24",
    "topic" : "1",
    "question" : "ЧТО ЗА МОД ИГРЫ?",
    "answer" : "<span style="color: rgb(36, 42, 48); font-family: RobotoRegular, sans-serif; line-height: 18.2px; background-color: rgb(255, 255, 255);">/*...*/</span>"
  }
}

(Igor Motov) #11

Ну, по крайней мере, мы движемся в правильном направлении - установки индекса в индексе появились. Теперь надо маппингом исправить. Я, думаю, проблема тут

        'mapping' => [
            'faq_article' => [
                '_source' => [

должно быть 'mappings' => ....


(system) #12