我正在开发一个具有Haystack搜索引擎功能的Django应用程序,并希望实现“类似google”的冒号搜索运算符。
在进行Google搜索时,您可以使用filetype:pdf
或site:www.stackoverflow.com
等查询来限制特定搜索结果,并希望实现类似的搜索方式。
我知道Solr,Haystack下面的搜索引擎之一可以在特定的领域做到这一点,但是如果在Haystack中有一个通用的方法,我很好奇。
我正在构建的当前解决方案是从表单中获取搜索输入,使用正则表达式搜索查找匹配\b[a-z]+:[\w\d]+\b
的字词,然后检查它们是否是合适的字段搜索和使用SearchQuerySet.filter
来限制结果。
但是,我希望有一种已经内置的方式来指定SearchIndex
中的野外可以自动以这种方式使用。这可能吗?
答案 0 :(得分:1)
您可以利用将词典扩展为关键字参数的能力
应用正则表达式过滤后,搜索字段和搜索值会创建一个类似
的字典my_search = {'search_field':'search_value'}
search_res = SearchQuerySet().filter(**my_search)
刚刚在我的实施中测试过,效果很好!除非您担心用户搜索他们不应该搜索/查看的字段,否则无需验证它是否是有效的搜索字段,无效的搜索字段将只返回无结果
答案 1 :(得分:1)
所以这实际上非常简单,因为Haystack提供了一种直接的方法来获取索引的所有字段:
connections[DEFAULT_ALIAS].get_unified_index()
所有需要做的就是对搜索字符串进行标记,删除任何具有有效字段的标记,并在使用过滤调用中的字段之前对剩余的条件运行搜索。
I've released it as a gist as well, but will probably end up packaging it at a later stage
from haystack.constants import DEFAULT_ALIAS
from haystack import connections
class TokenSearchForm(SearchForm):
def prepare_tokens(self):
try:
query = self.cleaned_data.get('q')
except:
return {}
opts = connections[DEFAULT_ALIAS].get_unified_index().fields.keys()
kwargs = {}
query_text = []
for word in query.split(" "):
if ":" in word:
opt,arg = word.split(":",1)
if opt in opts:
kwargs[str(opt)]=arg
else:
query_text.append(word)
self.query_text = " ".join(query_text)
self.kwargs = kwargs
return kwargs
def search(self):
self.query_text = None
kwargs = self.prepare_tokens()
if not self.is_valid():
return self.no_query_found()
if not self.cleaned_data.get('q'):
return self.no_query_found()
sqs = self.searchqueryset.auto_query(self.query_text)
if kwargs:
sqs = sqs.filter(**kwargs)
if self.load_all:
sqs = sqs.load_all()
return sqs