Jak wyszukiwać fragmenty tekstu w bazie danych

Czy są dostępne narzędzia open source lub komercyjne, które umożliwiają indeksowanie fragmentów tekstu zawartości bazy danych i mogą być wyszukiwane w Javie?

Podstawą pytania jest duża tabela bazy danych MySQL z kilkuset tysiącami rekordów, zawierająca kilka kolumn VARCHAR. W tych kolumnach ludzie chcieliby szukać fragmentów zawartości, więc indeks pełnotekstowy (oparty na granicach wyrazów) nie pomoże.

EDYTOWAĆ: [Dodano, aby wyjaśnić, dlaczego te pierwsze sugestie nie rozwiążą problemu:]

Dlatego wbudowany w MySQL indeks pełnotekstowy nie wykona zadania, podobnie jak Lucene czy Sphinx, z których wszystkie zostały zasugerowane w odpowiedziach. Patrzyłem już na oba te, ale o ile wiem, są one oparte na indeksowaniusłowa, wyłączając słowa stop i robiąc różnego rodzaju rozsądne rzeczy dla prawdziwego wyszukiwania pełnotekstowego. Jednak nie jest to odpowiednie, ponieważ mogę szukać szukanego hasła, takiego jak „oison”, które musi pasować do „Roisonic Street”, a także „Poison-Ivy”. Kluczowa różnica polega na tym, że wyszukiwane hasło jest po prostufragment treści kolumny, które nie muszą być ograniczone przez żadne znaki specjalne ani białe znaki.

EDIT2: [Dodano kilka dodatkowych informacji:] Wymagana funkcja, która ma zostać zaimplementowana na podstawie tego, to bardzo luźne wyszukiwanie opisów przedmiotów w systemie zarządzania towarami. Użytkownicy często nie znają właściwego numeru przedmiotu, ale tylko część nazwy przedmiotu. Niestety jakość tych opisów jest raczej niska, pochodzą one ze starszego systemu i nie można ich łatwo zmienić. Gdyby na przykład ludzie szukali młota saneczkowego, wchodziliby w „sanki”. Dzięki indeksowi opartemu na słowie / tokenach nie można by znaleźć dopasowań zapisanych jako „młot kowalski”, ale tylko ci, którzy słuchają „młota saneczkowego”. Istnieją różne rodzaje dziwnych wariacji, które muszą zostać uwzględnione, co sprawia, że ​​podejście oparte na tokenach jest niepraktyczne.

Obecnie jedyne, co możemy zrobić, toLIKE '%searchterm%' zapytanie, skutecznie wyłączając jakiekolwiek użycie indeksu i wymagające dużo zasobów i czasu.

Idealnie byłoby, gdyby każde takie narzędzie stworzyło indeks, który pozwoliłby mi bardzo szybko uzyskać wyniki dla podobnych zapytań, dzięki czemu mógłbym zaimplementować wyszukiwanie typu reflektorowego, pobierając tylko „prawdziwe” dane z tabeli MySQL za pomocą klucza podstawowego, gdy użytkownik wybierze rekord wyniku.

Jeśli to możliwe, indeks powinien być aktualizowalny (bez konieczności pełnej przebudowy), ponieważ dane mogą się zmienić i powinny być dostępne do natychmiastowego wyszukiwania przez innych klientów.

Z przyjemnością otrzymam rekomendacje i / lub raporty z doświadczeń.

EDIT3: Rozwiązanie komercyjne odkryło, że „po prostu działa” Mimo że dostałem wiele dobrych odpowiedzi na to pytanie, chciałem tutaj zauważyć, że w końcu poszliśmy z komercyjnym produktem o nazwie „QuickFind”, wyprodukowanym i sprzedanym przez niemiecką firmę „HMB Datentechnik”. Proszę zauważyć, że jestemnie związany z nimi w jakikolwiek sposób, ponieważ może się tak wydawać, gdy będę kontynuować i opisać, co może zrobić ich produkt. Niestety ichstronie internetowej wygląda raczej źle i jest tylko po niemiecku, ale sam produkt jest naprawdę świetny. Obecnie mam od nich wersję próbną - będziesz musiał się z nimi skontaktować, bez pobierania - i jestem pod ogromnym wrażeniem.

Ponieważ w Internecie nie ma pełnej dokumentacji, postaram się opisać moje dotychczasowe doświadczenia.

Tworzą niestandardowy plik indeksu oparty na zawartości bazy danych. Mogą się integrować za pośrednictwem ODBC, ale z tego, co mi powiedziano, klienci rzadko to robią. Zamiast tego - i prawdopodobnie tak zrobimy - generujesz eksport tekstu (np. CSV) z podstawowej bazy danych i przekazujesz go swojemu indeksatorowi. Pozwala to na całkowitą niezależność od rzeczywistej struktury tabeli (lub jakiejkolwiek bazy danych SQL); w rzeczywistości eksportujemy dane połączone z kilku tabel. Indeksy mogą być stopniowo aktualizowane później w locie.

Na tej podstawie ich serwer (zaledwie 250 kb, działający jako aplikacja konsoli lub usługa Windows) służy do nasłuchiwania zapytań na porcie TCP. Protokół jest oparty na tekście i wygląda na trochę „stary”, ale jest prosty i działa. Zasadniczo po prostu przekazujesz, który z dostępnych indeksów chcesz przeszukać, oraz wyszukiwane terminy (fragmenty), rozdzielone spacjami. Dostępne są trzy formaty wyjściowe: tablica HTML / JavaScript, XML lub CSV. Obecnie pracuję nad opakowaniem Java dla nieco „datowanego” protokołu przewodowego. Ale wyniki są fantastyczne: obecnie mam przykładowy zestaw danych zawierający około 500 000 rekordów z 8 indeksowanymi kolumnami, a moja aplikacja testowa uruchamia wyszukiwanie we wszystkich 8 kolumnach dla zawartości JTextFieldprzy każdym naciśnięciu klawisza podczas edycji i może aktualizować wyświetlanie wyników (JTable) w czasie rzeczywistym! Dzieje się tak bez przechodzenia do instancji MySQL, z której pochodzą dane. Opierając się na kolumnach, które otrzymasz, możesz poprosić o „oryginalny” rekord, wysyłając zapytanie do MySQL kluczem podstawowym tego wiersza (musi być oczywiście uwzględnione w indeksie QuickFind).

Indeks jest około 30-40% wielkości wersji danych eksportu tekstu. Indeksowanie wiązało się głównie z szybkością we / wy dysku; moje 500 000 rekordów zajęło około minuty lub dwóch do przetworzenia.

Trudno to opisać, ponieważ trudno mi było uwierzyć, kiedy zobaczyłem prezentację produktu w domu. Przedstawili 10-milionową bazę danych o wierszach i wyszukali fragmenty nazwisk, adresów i numerów telefonów, a po naciśnięciu przycisku „Szukaj” wyniki wróciły w ciągu sekundy - wszystko zrobione na notebooku! Z tego, co mi powiedziano, często integrują się z systemami SAP lub CRM, aby poprawić czas wyszukiwania, gdy agenci call center po prostu rozumieją fragmenty nazw lub adresów dzwoniącego.

W każdym razie prawdopodobnie nie będę lepiej opisywał tego. Jeśli potrzebujesz czegoś takiego, zdecydowanie powinieneś to sprawdzić.tłumacz Google robi dobrą robotę tłumacząc swoją stronę z niemieckiego na angielski, więc może to być dobry początek.

questionAnswers(10)

yourAnswerToTheQuestion