python - español - ¿Cómo usar la búsqueda de texto completo en la base de datos sqlite3 en django?
django tutorial (2)
Estoy trabajando en una aplicación django con la base de datos sqlite3, que tiene un contenido de base de datos fijo. Por fijo quiero decir que el contenido de la base de datos no cambiará con el tiempo. El modelo es algo como esto:
class QScript(models.Model):
ch_no = models.IntegerField()
v_no = models.IntegerField()
v = models.TextField()
Hay alrededor de 6500 registros en la tabla. Dado un texto que puede tener algunas palabras faltantes, o algunas palabras mal escritas, necesito determinar su ch_no
y v_no
. Por ejemplo, si hay un campo v
en db con el texto "Este es un ejemplo de verso" , un texto dado como "Este es un ejemplo de ejemplo " debería darme el ch_no
y el v_no
de db. Esto se puede hacer utilizando la búsqueda de texto completo, creo.
Mis consultas son:
¿Puede la búsqueda de texto completo hacer esto? Mi conjetura de lo que he estudiado, puede, como se dice en la página sqlite3 : las búsquedas de texto completo es "lo que Google, Yahoo y Bing hacen con los documentos colocados en la World Wide Web" . Citado en SO, también leí este artículo , junto con muchos otros, pero no encontré nada que se ajuste a mis requisitos.
¿Cómo usar FTS en los modelos django? Lo leí pero no ayudó. Parece demasiado anticuado Lea aquí que: "... requiere una manipulación directa de la base de datos para agregar el índice de texto completo" . La búsqueda proporciona principalmente información relacionada con MySQL, pero necesito hacerlo en sqlite3. Entonces, ¿cómo hacer esa manipulación directa en sqlite3?
Editar:
¿Es correcta mi elección de atenerme a sqlite3? ¿O debería usar algo diferente (como haystack + elasticsearch como dijo Alex Morozov )? Mi db no crecerá más, y he estudiado que para db de pequeño tamaño, sqlite casi siempre es mejor (mi situación coincide con la cuarta en sqlite cuando se usa checklist ).
El motor FTS de SQLite se basa en tokens: palabras clave que el motor de búsqueda intenta igualar.
Una variedad de tokenizers están disponibles, pero son relativamente simples. El tokenizador "simple" simplemente divide cada palabra y la minúscula: por ejemplo, en la cadena "El zorro marrón rápido salta sobre el perro flojo", la palabra "saltos" coincidiría, pero no "saltaría". El tokenizer "porter" es un poco más avanzado, eliminando las conjugaciones de palabras, de modo que "saltos" y "saltos" coincidirían, pero un error tipográfico como "jmups" no lo haría.
En resumen, la extensión SQLite FTS es bastante básica, y no pretende competir con, digamos, Google.
En cuanto a la integración de Django, no creo que haya ninguna. Es probable que necesite utilizar la interfaz de Django para consultas SQL sin formato, tanto para crear como para consultar la tabla FTS.
Creo que mientras sqlite es una increíble pieza de software, sus capacidades de búsqueda de texto completo son bastante limitadas. En cambio, podrías indexar tu base de datos usando la aplicación Haystack Django con algún programa de fondo como Elasticsearch . Tener esta configuración (y aún poder acceder a su base de datos sqlite) me parece la forma más robusta y flexible en términos de FTS.
Elasticsearch tiene una búsqueda difusa basada en la distancia de Levenshtein (en pocas palabras, manejaría sus consultas "egsample"). Entonces, todo lo que necesita es hacer un tipo correcto de consulta:
from haystack.forms import SearchForm
from haystack.generic_views import SearchView
from haystack import indexes
class QScriptIndex(indexes.SearchIndex, indexes.Indexable):
v = indexes.CharField(document=True)
def get_model(self):
return QScript
class QScriptSearchForm(SearchForm):
text_fuzzy = forms.CharField(required=False)
def search(self):
sqs = super(QScriptSearchForm, self).search()
if not self.is_valid():
return self.no_query_found()
text_fuzzy = self.cleaned_data.get(''text_fuzzy'')
if text_fuzzy:
sqs = sqs.filter(text__fuzzy=text_fuzzy)
return sqs
class QScriptSearchView(SearchView):
form_class = QScriptSearchForm
Actualización: siempre que PostgreSQL tenga la función de distancia Levenshtein, también podría aprovecharla como el back-end de Haystack, así como un motor de búsqueda independiente. Si elige la segunda manera, tendrá que implementar una expresión de consulta personalizada , que es relativamente fácil si está usando una versión reciente de Django.