Определяем список стоп слов для sphinxsearch

Чтобы sphixsearch не тормозил и не жрал много ресурсов, необходимо выбрасывать из индексации стоп слова, задавая их в конфиге индексов директивой stopwords = /usr/local/sphinx/stopwords.txt

По большей части, это различные часто употребляемые предлоги, междометия и короткие словечки. Да можно конечно не индексировать совсем короткие слова, указав min_word_len, но у нас стоит задача, чтобы поиск работал на лету и с первого символа.

Но где ж их взять, стоп слова? А вычленить из лога запросов sphinx. Там указывается и запрос и время ушедшее на него.

Соберем всё за неделю в один файл:

zcat /var/log/sphinxsearch/query.log.* >> query.log && cat /var/log/sphinxsearch/query.log >> query.log

Строки в лог файле запрсов выглядят так:

[Sun Aug  2 06:33:20.843 2020] 0.286 sec 0.286 sec [ext2/1/ext 109806 (0,50)] [index_name_1] test
[Tue Jul 28 05:29:19.464 2020] 2.272 sec 2.272 sec [ext2/0/ext 2 (0,20)] [index_name_2] Un grupo de estudiantes

И их там до хрена.

Задача — выбрать только те, у которых запросы более 1 секунды и разделить их по именам индексов — таблиц. Здесь не обойтись без команды awk

awk '$6>1{print}' query.log > query_long.log
awk '{print $13}' query_long.log | sort | uniq -c | sort -rn > query_users.txt
cat query_users.txt
  46285 [index_name_1]
   1616 [index_name_2]
   1066 [index_name_3]
    754 [index_name_4]
    647 [index_name_5]
     13 [index_name_6]

Теперь мы знаем, какие из индексов баз тормозят больше всего.

А теперь пожестим. Определяем топ 100 самых часто употребляемых слов, которые вызывают тормоза:

grep '\[index_name_1\]' query_long.log | sed -r 's/.*\[index_name_1\] //g' | sed -r 's/\W/ /g' | sed -r 's/[0-9]//g' | sed -r 's/\s+/ /g' | awk 'BEGIN {FS = " "}{for (x = 1; x <= NF; x++) { printf "%s%s",$x, "\n"}}' | sed -r 's/^[a-zA-Z]$//g' | sed '/^$/d' | sort | uniq -c | sort -rn | head -n 100

Какая милая глазу и легко перевариваемая, особенно для новичков, команда… Сохраним топ 20 из этой сотни в файл words.txt

grep '\[index_name_1\]' query_long.log | sed -r 's/.*\[index_name_1\] //g' | sed -r 's/\W/ /g' | sed -r 's/[0-9]//g' | sed -r 's/\s+/ /g' | awk 'BEGIN {FS = " "}{for (x = 1; x <= NF; x++) { printf "%s%s",$x, "\n"}}' | sed -r 's/^[a-zA-Z]$//g' | sed '/^$/d' | sort | uniq -c | sort -rn | head -n 20 | awk '{print $2}' >> words.txt

И так пройдемся по всем нашим базам и сохраним сколько надо. Выплюнем результаты без переносов строк в файл stopwords.txt

cat words.txt | sort | uniq | tr -s '\n' ' ' > stopwords.txt

Если у нас был старый файл, то объединим результаты, чтобы ничего не потерялось:

cat old_stopwords.txt words.txt | sort | uniq | tr -s '\n' ' ' > stopwords.txt

Осталось отнести готовый продукт на место, снова проиндексировать данные баз и перезапустить sphinx

cp stopwords.txt /usr/local/sphinx/stopwords.txt

Вот так.

Простая настройка и запуск Sphinx на debian для полнотекстового поиска на сайте

Оставить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *