В Firebird с помощью SIMILAR TO как найти совпадение нескольких слов - PullRequest
1 голос
/ 13 августа 2011

Я использую Firebird 2.5, и мне нужно найти строки, содержащие несколько слов в любом порядке:

найди 'синий' и 'дом':

«Голубой дом в лесу» = правда «дом с голубыми окнами» = правда «дом у пляжа» = ложь «синий автомобиль» = правда

Использование трубы "|" дайте мне ИЛИ, и мне нужно И, но в любом порядке, не только с 2 словами, может быть больше Я пытаюсь использовать SIMILAR TO, но кажется, что RegExpr в Firebird слишком ограничен.

Использование нескольких LIKE x и LIKE y - это не тот путь, по которому вы идете, потому что я не знаю, сколько слов нужно будет найти.

Ответы [ 3 ]

1 голос
/ 13 августа 2011

Вы можете решить свою задачу только средствами Firebird.Предположим, у вас есть таблица с именем TEST с единственным полем S.

CREATE TABLE TEST (S VARCHAR(256))

, которая содержит фразы:

  'a blue house in the woods' 
  'a house with blue windows' 
  'a house by the beach' 
  'the blue car'
  ...

Вам потребуется создать вспомогательную выбираемую процедуру SPLIT_WORDS:

CREATE OR ALTER PROCEDURE split_words (S VARCHAR(256))
  RETURNS(
    K VARCHAR(256),
    W VARCHAR(256))
AS
  DECLARE VARIABLE B INTEGER = 1;
  DECLARE VARIABLE E INTEGER = 1;
  DECLARE VARIABLE C CHAR(1);
BEGIN
  K = :S;
  WHILE (:E <= CHAR_LENGTH(:S)) DO
  BEGIN
    C = UPPER(SUBSTRING(:S FROM :E FOR 1));
    IF (:C < 'A' OR :C > 'Z') THEN
    BEGIN
      W = SUBSTRING(:S FROM :B FOR (:E - :B));

      IF (:W > '') THEN
        SUSPEND;

      WHILE (:E <= CHAR_LENGTH(:S)) DO
      BEGIN
        C = UPPER(SUBSTRING(:S FROM :E FOR 1));
        IF (:C >= 'A' AND :C <= 'Z') THEN
          LEAVE;
        E = :E + 1;
      END

      B = :E;
    END
    E = :E + 1;
  END

  W = SUBSTRING(:S FROM :B FOR (:E - :B));
  IF (:W > '') THEN
    SUSPEND;
END

Процедура, предназначенная для разбиения заданной строки на слова.Все символы, не являющиеся буквами, рассматриваются как разделители.

С помощью этой процедуры можно написать запрос, который вернет все строки со словами «HOUSE» и «BLUE» в любом порядке.

SELECT
  tt.s
FROM
  test tt JOIN
    (SELECT
        t.s, COUNT(s2.w) c
      FROM
        test t LEFT JOIN split_words(t.s) s ON 1=1
          LEFT JOIN split_words('blue house') s2 ON s.w=s2.w
      WHERE
        s2.w IS NOT NULL
      GROUP BY
        1
     ) ttt ON ttt.s = tt.s
WHERE
  ttt.c = (SELECT COUNT(*) FROM split_words('blue house'))
0 голосов
/ 13 августа 2011

Вы можете проверить ПОХОЖИЕ НА в справочном руководстве, но я думаю, что вам нужно что-то вроде Sphinx

0 голосов
/ 13 августа 2011

Насколько мне известно, в Firebird нет ничего, что могло бы вам помочь.

Что вам действительно нужно, так это полнотекстовый поиск.Хотя это не поддерживается напрямую Firebird, здесь есть несколько полезных советов: http://www.firebirdfaq.org/faq328/

Удачи и извините, у меня нет более прямого ответа.

...