Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Текстовые индексы. Быстрый поиск вида like '%&%' / 25 сообщений из 34, страница 1 из 2
18.02.2021, 18:02
    #40046816
Андрей_7777
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Добрый день!

БД на Oracle 19.5.
Есть таблица (50 миллионов строк), в которой нужно производить поиск подстроки (значения задаются пользователем) по нескольким текстовым полям (name1, name2, name3), например:

Код: sql
1.
2.
3.
4.
5.
select *
from my_table br
where br.name1 like '%12 34 567890%'
   or br.name2 like '%12 34 567890%'
   or br.name3 like '%12 34 567890%'



Поиск работает, но медленно. IN MEMORY не помогло (ускорило раза в 2 всего). Обычные индексы тут не помогут из-за левого %, поэтому были созданы текстовые индексы на каждое из полей поиска (name1, name2, name3).

Соответственно, запрос стал выглядеть следующим образом:
Код: sql
1.
2.
3.
4.
5.
select *
from my_table br
where CONTAINS(br.name1, '%12 34 567890%') > 0
   or CONTAINS(br.name2, '%12 34 567890%') > 0
   or CONTAINS(br.name3, '%12 34 567890%') > 0



Вроде бы проблема решилась, но недавно оказалось, что в текстовых индексах есть ограничения на повторяющиеся значения, и при поиске некоторых значений, например:
Код: sql
1.
2.
3.
select *
from my_table br
where CONTAINS(br.name1, '%34 57 123890%') > 0



возникает ошибка:
Код: sql
1.
2.
3.
ORA-29902: error in executing ODCIIndexStart() routine
ORA-20000: Oracle Text error:
DRG-51030: wildcard query expansion resulted in too many terms



Пробовали увеличивать параметр MAX_TERMS с 2000 до 50000, но не помогло, пересоздавали индекс так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
DECLARE
  PROCEDURE TryDropPreference(pPreference IN VARCHAR2)
  IS
  BEGIN
    FOR rec IN 
    (
      SELECT *
        FROM ctx_user_preferences p
       WHERE p.pre_name = UPPER(pPreference)
    )
    LOOP
      ctx_ddl.drop_preference(pPreference);
    END LOOP;
  END;
  
  PROCEDURE AddCtxIndex(pIndex IN varchar2, pTable IN VARCHAR2, pColumn IN VARCHAR2, pOnCommit IN VARCHAR2)
  IS
    lCnt NUMBER;
    lCommand VARCHAR2(4000 CHAR);
    lPref VARCHAR2(1000 CHAR);
    lLex VARCHAR2(1000 CHAR);
    lStore VARCHAR2(1000 CHAR);
  BEGIN
    SELECT COUNT(1)
      INTO lCnt
      FROM user_indexes i
     WHERE i.table_name = pTable
       AND i.index_name = pIndex
       AND i.index_type = 'DOMAIN';

    IF lCnt = 0 THEN
      lPref := 'PREF_'||pTable||'_'||pColumn;
      
      TryDropPreference(lPref);

      ctx_ddl.create_preference(lPref, 'BASIC_WORDLIST');
      ctx_ddl.set_attribute(lPref,'PREFIX_INDEX','TRUE');
      ctx_ddl.set_attribute(lPref,'SUBSTRING_INDEX', 'YES');
      ctx_ddl.set_attribute(lPref, 'WILDCARD_MAXTERMS', 50000);

      lLex := 'LEX_'||pTable||'_'||pColumn;
      
      TryDropPreference(lLex);

      ctx_ddl.create_preference(lLex,'BASIC_LEXER');
      ctx_ddl.set_attribute(lLex,'PRINTJOINS','_-''"$');

      lStore := 'PREF_STORE_'||pTable||'_'||pColumn;
      
      TryDropPreference(lStore);

      ctx_ddl.create_preference(lStore,'BASIC_STORAGE');
      ctx_ddl.set_attribute(lStore,'I_TABLE_CLAUSE','tablespace TIMELINE_EXCHANGE storage (initial 1M)');
      ctx_ddl.set_attribute(lStore,'K_TABLE_CLAUSE','tablespace TIMELINE_EXCHANGE storage (initial 1M)');
      ctx_ddl.set_attribute(lStore,'R_TABLE_CLAUSE','tablespace TIMELINE_EXCHANGE storage (initial 1M)');
      ctx_ddl.set_attribute(lStore,'N_TABLE_CLAUSE','tablespace TIMELINE_EXCHANGE storage (initial 1M)');
      ctx_ddl.set_attribute(lStore,'I_INDEX_CLAUSE','tablespace TIMELINE_EXCHANGE storage (initial 1M)');

      lCommand := '
      create index '||pIndex||' on '||pTable||' ('||pColumn||') indextype is ctxsys.context PARAMETERS (''lexer '||lLex
      ||' wordlist '||lPref||' storage '||lStore||' memory 200M '||pOnCommit||''')';

      EXECUTE IMMEDIATE lCommand;
      dbms_output.put_line(lCommand);
    END IF;
  END;
  
 
BEGIN
  AddCtxIndex('MY_TABLE_CTX','MY_TABLE','NAME1','');
END;
/



Подскажите, пожалуйста. Может быть я как-то неправильно создаю индексы? Может у кого-нибудь есть опыт использования текстовых индексов для решения подобных проблем?

Или может реализовывали создание своих поисковых систем? Я уже думаю над созданием отдельной таблицы, в которую наинсертить все возможные подстроки, создать на нее индекс и искать в ней по like только с правым %, т.е. например, для значения "12 34 567890" во вспомогательную таблицу наинсертятся значения:
12 34 567890
2 34 567890
34 567890
4 567890
567890
67890
7890
890
90
0

Только вот пока не очень представляю, какие сложности могут возникнуть над сопровождением такой таблицы.
...
Рейтинг: 0 / 0
18.02.2021, 18:34
    #40046834
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Андрей_7777,

Код: plsql
1.
CONTAINS(br.name1, '%34 57 123890%') > 0


Вам надо почитать про операторы contains. То что вы вводите ищет на самом деле: name like '%34' or name like '57' or name like 123890%'
...
Рейтинг: 0 / 0
18.02.2021, 18:41
    #40046836
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Андрей_7777
Или может реализовывали создание своих поисковых систем? Я уже думаю над созданием отдельной таблицы, в которую наинсертить все возможные подстроки, создать на нее индекс и искать в ней по like только с правым %, т.е. например, для значения "12 34 567890" во вспомогательную таблицу наинсертятся значения:
12 34 567890
2 34 567890
34 567890
4 567890
567890
67890
7890
890
90
0

Только вот пока не очень представляю, какие сложности могут возникнуть над сопровождением такой таблицы.
для начала - вы ее размеры примерно вычислили?
...
Рейтинг: 0 / 0
18.02.2021, 18:41
    #40046837
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Помимо этого, вас надо ещё прочитать про то как добавить пробел в "токены" (printjoins, skipjoins)
...
Рейтинг: 0 / 0
18.02.2021, 20:42
    #40046878
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Андрей_7777
по нескольким текстовым полям (name1, name2, name3)
А что это за поля? они поддаются нормализации?
...
Рейтинг: 0 / 0
19.02.2021, 01:31
    #40046958
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
miksoft
Андрей_7777
по нескольким текстовым полям (name1, name2, name3)
А что это за поля? они поддаются нормализации?

Шаблон поиска очень похож на номер паспорта.
Наверняка персональные данные длинной строкой.
...
Рейтинг: 0 / 0
19.02.2021, 06:57
    #40046973
Андрей_7777
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Sayan Malakshinov
Помимо этого, вас надо ещё прочитать про то как добавить пробел в "токены" (printjoins, skipjoins)


Sayan Malakshinov, cпасибо большое.

Попробовал добавить пробел в токен следующим образом (перед символом _ указал пробел):
Код: sql
1.
2.
      ctx_ddl.create_preference(lLex,'BASIC_LEXER');
      ctx_ddl.set_attribute(lLex,'PRINTJOINS',' _-''"$');


Но это не помогло, проблемный select заваливается с той же ошибкой.

Также пробовал исключать пробел:
Код: sql
1.
2.
3.
4.
      ctx_ddl.create_preference(lLex,'BASIC_LEXER');
      ctx_ddl.set_attribute(lLex,'PRINTJOINS','_-''"$');
      ctx_ddl.set_attribute(lLex,'SKIPJOINS',' ');
;



Тоже не помогло, видимо из-за этого:
whitespace
Specify the characters that are treated as blank spaces between tokens.
BASIC_LEXER uses whitespace characters in conjunction with punctuations and newline characters to identify character strings that serve as sentence delimiters for sentence and paragraph searching.
The predefined default values for whitespace are space and tab. These values cannot be changed.
Specifying characters as whitespace characters adds to these defaults.

Не знаете, как сделать, чтобы пробел обрабатывался, как обычный символ?
...
Рейтинг: 0 / 0
19.02.2021, 06:59
    #40046974
Андрей_7777
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
andreymx
Андрей_7777
Или может реализовывали создание своих поисковых систем? Я уже думаю над созданием отдельной таблицы, в которую наинсертить все возможные подстроки, создать на нее индекс и искать в ней по like только с правым %, т.е. например, для значения "12 34 567890" во вспомогательную таблицу наинсертятся значения:
12 34 567890
2 34 567890
34 567890
4 567890
567890
67890
7890
890
90
0

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


andreymx,

Количество строк в ней примерно вычислил, несколько миллиардов получается, это не очень большой размер для нашей БД.
Я понимаю, что это кривое решение, просто рассматриваю все варианты.
...
Рейтинг: 0 / 0
19.02.2021, 07:03
    #40046975
Андрей_7777
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Правильный Вася
miksoft
пропущено...
А что это за поля? они поддаются нормализации?

Шаблон поиска очень похож на номер паспорта.
Наверняка персональные данные длинной строкой.


Все верно, это шаблон паспорта, в других полях он тоже может быть. Поля нормализации не поддаются.
...
Рейтинг: 0 / 0
19.02.2021, 08:36
    #40046984
Андрей_7777
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
[quot Андрей_7777#22283232]
Sayan Malakshinov

...
Не знаете, как сделать, чтобы пробел обрабатывался, как обычный символ?


Или м.б. создать в таблице дополнительные поля, в которых будут храниться значения без пробелов, и создать на них текстовые индексы?
...
Рейтинг: 0 / 0
19.02.2021, 12:50
    #40047091
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Андрей_7777,

А таблица сильно широкая? Какая средняя длина записи?
...
Рейтинг: 0 / 0
19.02.2021, 14:13
    #40047138
Андрей_7777
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
miksoft
Андрей_7777,

А таблица сильно широкая? Какая средняя длина записи?


Средняя длина поля 20 символов
...
Рейтинг: 0 / 0
19.02.2021, 14:24
    #40047143
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Андрей_7777Все верно, это шаблон паспорта

Тогда откуда приходит этот шаблон, что он проверяется на вхождение, а не на полное
совпадение? Типа "я помню только три цифры в середине, остальное забыл"?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
19.02.2021, 14:59
    #40047157
123йй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Dimitry Sibiryakov,

очень похоже что у ТС сделаны 3 поля как Документ1,Документ2,Документ3.
типа загран, паспорт и водительское.
в какое поле, что попадет никто не знает.
вот он и пытается это решить :)
...
Рейтинг: 0 / 0
19.02.2021, 15:01
    #40047160
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Вопрос-то не в этом. Какой документ ни возьми, при поиске по его номеру его (номер) всегда
набирают с самой первой цифры, никто не вырывает пару из середины. Поэтому непонятно
почему у него лайк с двумя процентами.


PS: Единственная не слишком безумная причина для такого - нарушение первой НФ, в поле записаны несколько номеров через запятую.
...
Рейтинг: 0 / 0
19.02.2021, 15:03
    #40047161
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Dimitry Sibiryakov
при поиске по его номеру его (номер) всегда
набирают с самой первой цифры, никто не вырывает пару из середины.
не говоря уже о пробелах внутри номера...
...
Рейтинг: 0 / 0
19.02.2021, 15:57
    #40047186
123йй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
"Паспорт РФ 1234 567890 выдан...."
возможно
...
Рейтинг: 0 / 0
19.02.2021, 16:15
    #40047199
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
123ййвозможно

В этом случае топикстартер врёт и для нормализации ещё поле непаханное.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
19.02.2021, 17:03
    #40047232
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Dimitry Sibiryakov
Вопрос-то не в этом. Какой документ ни возьми, при поиске по его номеру его (номер) всегда
набирают с самой первой цифры, никто не вырывает пару из середины.


Не забываем про силовые органы: Свидетель запомнил несколько цифр из середины номера машины :).

SY.
...
Рейтинг: 0 / 0
19.02.2021, 18:02
    #40047273
Андрей_7777
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Dimitry Sibiryakov
Вопрос-то не в этом. Какой документ ни возьми, при поиске по его номеру его (номер) всегда
набирают с самой первой цифры, никто не вырывает пару из середины. Поэтому непонятно
почему у него лайк с двумя процентами.


PS: Единственная не слишком безумная причина для такого - нарушение первой НФ, в поле записаны несколько номеров через запятую.


Да, вы правы, нарушение первой НФ действительно есть.
Но тому есть веские причины - данные приходят из разных источников, в каждом источнике много разных форматов данных, в том числе и не известных заказчику. Форматы могут обновляться, а также добавляться новые (без предупреждения), а также, нередко, человеческий фактор оказывает воздействие.
Заказчик может слабо влиять на форматы предоставляемых ему данных. Поэтому и выбран такой способ хранения данных. Особо это нигде не аукается, а также у такого способа есть свои плюсы.
Я сам перфекционист по натуре и стараюсь все делать оптимально, но, есть теория, а есть жизнь, в которой не всегда возможно сделать все идеально.
...
Рейтинг: 0 / 0
19.02.2021, 18:10
    #40047278
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Андрей_7777Но тому есть веские причины - данные приходят из разных источников, в каждом источнике
много разных форматов данных, в том числе и не известных заказчику. Форматы могут
обновляться, а также добавляться новые (без предупреждения), а также, нередко,
человеческий фактор оказывает воздействие.

Весь список состоит из одного "лень". Проблема в том, что при таких условиях и ваш поиск с
фиксированным форматом не будет работать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
19.02.2021, 18:30
    #40047284
Андрей_7777
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Dimitry Sibiryakov

Андрей_7777Но тому есть веские причины - данные приходят из разных источников, в каждом источнике
много разных форматов данных, в том числе и не известных заказчику. Форматы могут
обновляться, а также добавляться новые (без предупреждения), а также, нередко,
человеческий фактор оказывает воздействие.

Весь список состоит из одного "лень". Проблема в том, что при таких условиях и ваш поиск с
фиксированным форматом не будет работать.


Весь список состоит из одного "лень".

Это не лень, просто заказчика устраивает текущее положение дел и он не хочет заниматься согласовыванием многочисленных форматов.

Проблема в том, что при таких условиях и ваш поиск с фиксированным форматом не будет работать.

Не совсем понял вас. Мне нужно всего лишь найти строки с данной подстрокой. Текстовый индекс для этого отлично подходит. Проблема только в том, что пробелы разделяют токены, а мне надо, чтобы они считались частью слов, но на сколько я понял из чтения документации это невозможно. Поэтому я хочу создать вспомогательные столбцы, в которых будут храниться значения без пробелов, и навесить на них текстовые индексы. По таким индексам будут находиться нужные мне значения (искать надо будет тоже без пробелов). Единственное, мне не нравится, то что надо создавать дополнительные столбцы, в идеале хотелось бы обойтись без них, но не знаю как это сделать, текстовый индекс по функции, например, replace(name, ' ') создать нельзя.
...
Рейтинг: 0 / 0
19.02.2021, 18:42
    #40047289
кит северных морей
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Андрей_7777
, текстовый индекс по функции, например, replace(name, ' ') создать нельзя.
виртуальной колонкой обмануть не пробовали?
...
Рейтинг: 0 / 0
19.02.2021, 18:43
    #40047290
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
А мне вообще смысл "обмануть" не понятен.
Ну обманит его топик стартер, получит просто замену обычному индексу.

IMHO
...
Рейтинг: 0 / 0
19.02.2021, 18:52
    #40047292
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Текстовые индексы. Быстрый поиск вида like '%&%'
Алгоритмически, я-бы свёл задачу к поиску документов с 3 токенами.

Тоесть вот такое

Код: plsql
1.
2.
3.
4.
5.
select *
from my_table br
where CONTAINS(br.name1, '%12 34 567890%') > 0
   or CONTAINS(br.name2, '%12 34 567890%') > 0
   or CONTAINS(br.name3, '%12 34 567890%') > 0



Заменить на
Код: plsql
1.
2.
3.
select *
from my_table br
where CONTAINS(br.name1, '12 AND 34 AND 567890') .... e.t.c.



А уже из оставшейся выборки добить обычным фильтром композицию этих токенов в правильном порядке.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Текстовые индексы. Быстрый поиск вида like '%&%' / 25 сообщений из 34, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]