我正在使用具有固定数据库内容的sqlite3数据库的django应用程序。固定的意思是db的内容不会随着时间的推移而改变。模型是这样的:
class QScript(models.Model):
ch_no = models.IntegerField()
v_no = models.IntegerField()
v = models.TextField()
表中有大约6500条记录。如果文字可能包含某些单词,或者某些单词拼写错误,我需要确定其ch_no
和v_no
。例如,如果db中有一个v
字段,其中包含文本"这是一个示例" ,一个给定的文本,如"这是一个egsample verse" 应该从db给我ch_no
和v_no
。这可以使用我认为的全文搜索来完成。
可以全文搜索吗?根据我所研究的内容,我可以如sqlite3 page所说:全文搜索是"谷歌,雅虎和必应对万维网上的文件做了什么&#34 ; 。引用SO,我和其他许多人一起阅读this article,但没有发现密切符合我要求的任何内容。
如何在django模型中使用FTS?我看过this但它没有帮助。它似乎太过时了。阅读here:" ...需要直接操纵数据库以添加全文索引" 。搜索主要提供MySQL相关信息,但我需要在sqlite3中完成。那么如何在sqlite3中做直接操作?
我选择坚持sqlite3是否正确?或者我应该使用不同的东西(如Alex Morozov所说的haystack + elasticsearch)?我的数据库不会变得更大,我研究过,对于小型数据库,sqlite 几乎总是更好(我的情况与第四个in sqlite's when to use checklist相匹配)。
答案 0 :(得分:2)
SQLite's FTS engine基于令牌 - 搜索引擎尝试匹配的关键字。
有各种各样的标记器,但它们相对简单。 "简单" tokenizer简单地将每个单词拆分并将其缩小:例如,在字符串中#34;快速的棕色狐狸跳过懒狗",单词"跳跃"会匹配,但不会#34;跳跃"。 "搬运工" tokenizer更先进一些,剥离了单词的结合,以便"跳跃"和"跳跃"会匹配,但是像#" jmups"不会。
简而言之,SQLite FTS扩展是相当基础的,并不意味着与谷歌竞争。
至于Django整合,我不相信有任何东西。您可能需要use Django's interface for raw SQL queries来创建和查询FTS表。
答案 1 :(得分:1)
我认为虽然sqlite是一个了不起的软件,但它的全文搜索功能非常有限。相反,您可以使用Haystack Django应用程序为您的数据库建立索引,并使用Elasticsearch之类的后端。在我看来,这种设置(并且仍能访问您的sqlite数据库)在FTS方面是最强大和最灵活的方式。
Elasticsearch有一个fuzzy search基于Levenshtein距离(简而言之,它会处理你的" egsample"查询)。所以你需要的是做出正确的查询类型:
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
更新:只要PostgreSQL具有Levenshtein距离功能,您也可以将其用作Haystack后端以及独立的搜索引擎。如果您选择第二种方式,则必须实施custom query expression,如果您使用的是最新版本的Django,则相对容易。