Неверно считается exact_hit?

Установил manticore с нуля. Создал тестовый индекс с 3 записями.

id | skus
1661 | iphone 17
1662 | iphone 17 pro max
1665 | iphone

Выполняю SQL запрос:

SELECT *, weight(), PACKEDFACTORS() FROM productstestindex WHERE MATCH (‘iphone’) OPTION ranker=expr(‘1’).

И у всех трех строк получаю идентичные факторы:

bm25=689, bm25a=0.82075059, field_mask=1, doc_word_count=1, field0=(lcs=1, hit_count=1, word_count=1, tf_idf=0.41697574, min_idf=0.41697574, max_idf=0.41697574, sum_idf=0.41697574, min_hit_pos=1, min_best_span_pos=1, exact_hit=0, max_window_hits=1, min_gaps=0, exact_order=1, lccs=1, wlccs=0.41697574, atc=0.000000), word0=(tf=1, idf=0.41697574)

Насколько я понимаю, у последней записи exact_hit должен быть 1?

Из-за этого тот же встроенный ранкер sph04 выдает мне одинаковый вес всем трем документам при запросе “iphone”.

Конфигурации тестировал разные, сейчас следующая:

index productstestindex {
    source          = productstest
    path            = /var/lib/manticore/data/productstestindex

    morphology = stem_ru
    min_word_len = 2

    index_exact_words = 1
    min_infix_len = 2

    ignore_chars = -

    blend_chars = +, &, U+23
    blend_mode = trim_all

    charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+0435, U+451->U+0435

    html_strip      = 0
}

Не повторяется на последней версии:

mysql> drop table if exists t; create table t(f text); insert into t values(1, 'iphone 17'),(2, 'iphone 17 pro max'),(3, 'iphone'); select *, weight(), packedfactors() from t where match('iphone') option ranker=expr('1');
--------------
drop table if exists t
--------------

Query OK, 0 rows affected (0.03 sec)

--------------
create table t(f text)
--------------

Query OK, 0 rows affected (0.02 sec)

--------------
insert into t values(1, 'iphone 17'),(2, 'iphone 17 pro max'),(3, 'iphone')
--------------

Query OK, 3 rows affected (0.01 sec)

--------------
select *, weight(), packedfactors() from t where match('iphone') option ranker=expr('1')
--------------

+------+-------------------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id   | f                 | weight() | packedfactors()                                                                                                                                                                                                                                                                                                                                                 |
+------+-------------------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|    1 | iphone 17         |        1 | bm25=319, bm25a=0.19519952, field_mask=1, doc_word_count=1, field0=(lcs=1, hit_count=1, word_count=1, tf_idf=-0.39624062, min_idf=-0.39624062, max_idf=-0.39624062, sum_idf=-0.39624062, min_hit_pos=1, min_best_span_pos=1, exact_hit=0, max_window_hits=1, min_gaps=0, exact_order=1, lccs=1, wlccs=-0.39624062, atc=0.000000), word0=(tf=1, idf=-0.39624062) |
|    2 | iphone 17 pro max |        1 | bm25=319, bm25a=0.19519952, field_mask=1, doc_word_count=1, field0=(lcs=1, hit_count=1, word_count=1, tf_idf=-0.39624062, min_idf=-0.39624062, max_idf=-0.39624062, sum_idf=-0.39624062, min_hit_pos=1, min_best_span_pos=1, exact_hit=0, max_window_hits=1, min_gaps=0, exact_order=1, lccs=1, wlccs=-0.39624062, atc=0.000000), word0=(tf=1, idf=-0.39624062) |
|    3 | iphone            |        1 | bm25=319, bm25a=0.19519952, field_mask=1, doc_word_count=1, field0=(lcs=1, hit_count=1, word_count=1, tf_idf=-0.39624062, min_idf=-0.39624062, max_idf=-0.39624062, sum_idf=-0.39624062, min_hit_pos=1, min_best_span_pos=1, exact_hit=1, max_window_hits=1, min_gaps=0, exact_order=1, lccs=1, wlccs=-0.39624062, atc=0.000000), word0=(tf=1, idf=-0.39624062) |
+------+-------------------+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)
--- 3 out of 3 results in 0ms ---

У последнего результата, как видно, exact_hit=1

Из-за этого тот же встроенный ранкер sph04 выдает мне одинаковый вес всем трем документам при запросе “iphone”.

select *, weight(), packedfactors() from t where match('iphone') option ranker=sph04
--------------

+------+-------------------+----------+-----------------+
| id   | f                 | weight() | packedfactors() |
+------+-------------------+----------+-----------------+
|    3 | iphone            |     7319 |                 |
|    1 | iphone 17         |     6319 |                 |
|    2 | iphone 17 pro max |     6319 |                 |
+------+-------------------+----------+-----------------+
3 rows in set (0.01 sec)
--- 3 out of 3 results in 1ms ---

Подскажите, на какую ОС ставили? Я тестировал на 13.13 версии мантикор. Проверял на ubuntu 24 и на ubuntu 22 (на arm).

Да, ваш вариант протестировал. Ровно по вашим запросам если идти, то всё работает, спасибо!

Но у меня индекс создаётся на основе данных из MySQL (конфиг выше приложил), и там ровно такой же запрос и такая же строка в индексе выдаёт exact_hit = 9

Продолу описывать наблюдения.

У меня основной запрос в source:

sql_query = SELECT id FROM shop_product

Если я сделаю так:

sql_query = SELECT id, ‘iphone‘ FROM shop_product

То exact_hit работает как надо.

В моем же случае выбирается только id, а остальные данные присоединяются (sql_joined_field), чуть упрощенный вид запроса:

sql_joined_field = skus from query; SELECT product_id, skus FROM table_name ORDER BY product_id

И вот тут уже exact_hit = 0.

Даже если я вот так делаю:

SELECT product_id, ‘iphone’ as skus FROM shop_product_skus GROUP BY product_id ORDER BY product_id

То есть ‘iphone’ слова указано статикой в конфиге, то всё равно 0.

Можете собрать минимальный пример для воспроизведения с нуля (можно с дампом mysql) и завести issue на гитхабе? Похоже на баг.