2009-12-10 10 views
9

Chciałbym zaimplementować wyszukiwanie pełnotekstowe w aplikacji na iPhone'a. Mam dane przechowywane w bazie danych SQLite, do której uzyskuję dostęp za pośrednictwem struktury Core Data. Po prostu użycie predykatów i ORing pęczku zdań "zawiera [cd]" dla każdego szukanego słowa i kolumny nie działa dobrze.Wyszukiwanie pełnotekstowe w Core Data Framework firmy Apple

Co zrobiliście, wydaje się, że działa dobrze?

+1

To jest bardzo blisko poprzedniego pytania: http://stackoverflow.com/questions/1862771/sqlite-indexing-performance-advice –

+2

Tak, ale otrzymywałem odpowiedzi, które były mniej związane z Core Data i więcej związane z sqlite . Postanowiłem stworzyć kolejną, która jest bardziej specyficzna dla Core Data. – getWeberForStackExchange

Odpowiedz

9

Mamy FTS3 działa bardzo ładnie na ponad 150 000 rekordów. Otrzymujemy podsegmenty czasów zapytań, które zwracają ponad 200 wyników w jednym zapytaniu ze słowem kluczowym.

Obecnie jedynym sposobem, aby Sqlite FTS3 działający na iPhonie, jest skompilowanie własnego pliku binarnego i połączenie go z projektem. Według mojej wiedzy pliki binarne zawarte w twoim projekcie nie będą działać z danymi podstawowymi. Być może Apple włączy opcję kompilatora FTS3 w przyszłej wersji?

Nadal można połączyć w swój własny plik binarny Sqlite FTS3 i używać go tylko do przeszukiwania pełnotekstowego. Byłoby to bardzo podobne do sposobu, w jaki Sphinx lub Lucene są używane w środowiskach aplikacji internetowych. Zauważ, że w pewnym momencie będziesz musiał zaktualizować indeks wyszukiwania, aby zachować synchronizację z magazynami Core Data.

Powodzenia !!

+1

Dzięki crunchyt, mam nadzieję, że włączą tę opcję. – getWeberForStackExchange

0

Używam contains[cd] w moim predykacie i działa dobrze. Być może mógłbyś opublikować swój predykat i moglibyśmy zobaczyć, czy jest oczywisty błąd.

+0

Przepraszam, miałem na myśli, że nie działa dobrze, na przykład pod względem wydajności. Opublikuję orzeczenie, kiedy wrócę do domu z pracy. Dzięki! – getWeberForStackExchange

1

Zakładam, że przez "nie działa dobrze" masz na myśli "źle działa". Wyszukiwanie pełnotekstowe jest zawsze stosunkowo powolne, szczególnie w środowiskach o ograniczonej przestrzeni lub pamięci. Możesz przyspieszyć działanie, upewniając się, że atrybuty, których szukasz, są indeksowane i używają BEGINSWITH[cd] zamiast CONTAINS[cd]. Moje przypomnienie (obecnie nie można znaleźć posta kakao) polega na tym, że SQLite użyje indeksu do dopasowywania prefiksów, ale powróci do wyszukiwania liniowego w poszukiwaniu infiksów.

+0

OK, co ma sens. Mam zamiar to wypróbować. – getWeberForStackExchange

+2

Barry Wark Sse "Wyszukiwanie pełnotekstowe jest zawsze względnie powolne" Jest to niepoprawne, być może z powodu nieporozumienia co to jest wyszukiwanie pełnotekstowe? Wyszukiwanie podciągu, które przekłada się na instrukcję SQL LIKE, jest powolne, ponieważ każdy wiersz musi zostać przeskanowany. Nie jest to zwykle określane jako "wyszukiwanie pełnotekstowe". Wyszukiwanie pełnotekstowe (to znaczy korzystanie z indeksu pełnotekstowego) jest często szybkie, zdecydowanie szybciej niż instrukcje SQL LIKE. Podam więcej szczegółów w odpowiedzi poniżej. :) – pchap10k

0

Sqlite posiada własny moduł indeksowania pełny tekst: http://sqlite.org/fts3.html

trzeba mieć pełną kontrolę nad SQL wysyłanej do db (nie wiem jak działa Rdzeń danych), ale przy pełnej indeksowanie tekstu moduł jest kluczem do szybkości wykonywania i prostoty instrukcji SQL SELECT, które wykonują wyszukiwanie pełnotekstowe.

Używanie ZAWIERA jest w porządku, jeśli nie potrzebujesz szybkiego wykonywania, ale wybrane przez niego wykonane nie mogą korzystać ze zwykłych indeksów, więc są przeznaczone do spowolnienia, a im większa baza danych tym wolniej. Korzystanie z prawdziwego indeksowania pełnotekstowego pozwala na ten sam rodzaj wyszukiwania, co w przypadku "ZAWIERA", ale rzeczy są indeksowane w celu uzyskania szybkich wyników, nawet przy dużych bazach danych.

0

Pracuję nad tym samym problemem i właśnie przejrzałem, aby śledzić na my post about this from a few weeks ago. Zamiast używać ZAWIERA, utworzyłem osobną jednostkę z instancją dla każdego kanonicznego słowa. Dodałem indeks do słów (w konstruktorze modeli XCode) i mogę użyć operatora BEGINSWITH do wykorzystania indeksu. Niemniej jednak, jako I just posted a few minutes ago, czas zapytania jest wciąż bardzo wolny nawet dla małych zestawów danych.

Musi istnieć lepszy sposób! Wszak widzimy tego rodzaju wyszukiwanie pełnotekstowe w wielu aplikacjach!

+0

To wydaje się być drogą. Zrobię to. – getWeberForStackExchange

+0

Hej, dk, czy udało Ci się przyspieszyć wyszukiwanie? Zrobiłem to samo co powyżej i nadal było dość wolno, jak wspomniałeś. – getWeberForStackExchange

+0

Weber, Znalazłem sukces, usuwając odwrotną relację, która zmodyfikowała schemat i znacznie przyspieszyła wyszukiwanie. Ale nadal nie testowałem na w pełni załadowanym DB i martwię się o nadymanie z powodu nowego schematu. Zobacz komentarze w artykule połączonym powyżej. –

Powiązane problemy