Django搜索:设置Haystack_Default_Operator='OR'无效
我正在使用Haystack和Whoosh来为我正在构建的Django网站实现搜索功能。我想在搜索词上使用“或”操作符(例如,“搜索字符串”会找到包含“搜索”或“字符串”的对象,而不是同时包含“搜索”和“字符串”的对象)。
这看起来很简单,因为Haystack允许你通过在settings.py文件中设置 HAYSTACK_DEFAULT_OPERATOR = 'OR' 来覆盖默认的“与”操作符。
不幸的是,将这个添加到我的settings.py中并没有产生任何效果。我在StackOverflow上找到了一些与此行为相关的参考,但没有找到解决方案。我还在GitHub上发现了一个问题,但这个问题自去年以来就没有得到任何评论或分类。
我可能做错了什么,所以我想在这里发帖看看是否有解决方案。没有解决方案我有点卡住了!
我在settings.py中的Haystack设置:
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'),
},
}
HAYSTACK_DEFAULT_OPERATOR = 'OR'
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
我的视图:
from haystack import views as hsviews
def search_test(request):
return hsviews.basic_search(request)
我的search_indexes.py文件:
import datetime
from haystack import indexes
from myApp.models import MyModel
from django.contrib.auth.models import User
class MyModelIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.NgramField(document=True, use_template= True)
isPublic = indexes.BooleanField(model_attr='isPubliclyVisible')
brand = indexes.CharField(model_attr='brand')
model = indexes.CharField(model_attr='model')
owner = indexes.CharField(model_attr='owner')
owner_username = indexes.CharField()
obj_type = indexes.CharField()
def get_model(self):
return MyModel
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(isPubliclyVisible = True)
def prepare_owner_username(self, obj):
return obj.owner.user.username
def prepare_obj_type(self,obj):
return 'MyModel'
我确实找到了一种变通方法(我还没有测试/考虑过是否适合我的解决方案),但我觉得这值得单独发个问题,以防我/我们做错了什么。
1 个回答
1
与其使用Haystack自带的basic_search函数,不如自己写一个视图,这样你可以更好地控制搜索查询的方式。这样一来,你就可以通过扩展视图或自定义搜索查询函数来处理更复杂的搜索,而且测试起来也会更简单。
举个例子,你可以为每个你要搜索的关键词建立单独的SearchQuerySet过滤器,然后把它们用“或”连接起来,像这样:
def get_query(request):
"""
This function retrieves any query terms (e.g q=search+term)
from the request object.
:param request: request object
:returns: query terms as a list (split on whitespace)
"""
query = None
qs_keyword = 'q'
if (qs_keyword in request.GET) and request.GET[qs_keyword].strip():
query_string = request.GET[qs_keyword]
query = query_string.split()
return query
def perform_query(request):
"""
This is a helper function to perform the actual query.
You can extend this to handle more complicated searches using AND,
OR, boolean qualifiers, etc.
:param request: request object
:returns: SearchQuerySet results
"""
query = get_query(request)
if not query:
results = EmptySearchQuerySet()
else:
results = SearchQuerySet()
for search_term in query:
# you can use the "|" (or) operator
results |= results.filter(content=search_term)
# or else use "filter_or"
# results = results.filter_or(content=search_term)
return results
def your_search_view(request, *args, **kwargs):
"""
This is your search view to process the query and display your results.
"""
# call "perform_query" to do the actual search
results = perform_query(request)
# do the rest of your view processing ...
return render_to_response(etc.)