Django haystack按标题排序结果

Django haystack按标题排序结果,django,solr,django-haystack,Django,Solr,Django Haystack,我想按标题对django haystack查询的结果进行排序 from haystack.query import SearchQuerySet for result in SearchQuerySet().all().order_by('result_title_sort'): print result.result_title_sort 但是,我一直遇到这个错误: 字段“result\u title\u sort”中的术语比文档多,但不可能在标记化字段上排序 这是我的haystac

我想按标题对django haystack查询的结果进行排序

from haystack.query import SearchQuerySet
for result in SearchQuerySet().all().order_by('result_title_sort'):
    print result.result_title_sort
但是,我一直遇到这个错误:

字段“result\u title\u sort”中的术语比文档多,但不可能在标记化字段上排序

这是我的haystack字段定义:

result_title_sort = CharField(indexed=True, model_attr='title')

我应该如何定义字段,以便对其进行排序?

如果字符串已标记(即有空格),Solr将不允许对字符串列进行排序。我希望您的标题有不止一个标记(单词),因此会出现错误


“字符串术语值可以包含任何有效字符串,但不应标记化。这些值根据其自然顺序进行排序。”从开始,您需要确保排序字段在SOLR中未标记化。从Haystack文档中不太清楚如何使用Haystack使其非标记化。我的解决方案是更改Haystack生成的SOLR schema.xml,使字段类型为“string”而不是“text”。因此,不要在schema.xml中包含类似的内容:

<field name="result_title_sort" type="text" indexed="true" stored="true" multiValued="false" />
然后需要在search_indexes.py中添加一个prepare方法来调用格式化程序,如

def prepare_result_title_sort(self,obj):
    return format_text_for_sort( obj.title, remove_articles=True )

最终,我通过滥用
faceted=True
找到了解决方法。它使haystack为charfield生成一个
type=“string”
字段。这是SOLR schema.xml中唯一更改的内容

result_title_sort = CharField(indexed=True, faceted=True)

def prepare_result_title_sort(self, article):
    return slugify(article.title.lower())
现在可以对结果进行排序:

results = results.order_by('result_title_sort_exact')
谢谢Mark Chackerian,您的解决方案确实适用于排序。但是,修改自动生成的
schema.xml
的输出时,我仍然感到有点不舒服。我通过使用Solr的字段类型找到了一个解决方案。Django Haystack文档并不清楚如何使用动态字段,但基本上如果您只是在
SearchIndex
prepare()
返回的
dict
中包含一个新键,那么
dynamicField
将在索引时添加到文档中

SearchIndex

\result\u title\u sort=CharField(index=True,model\u attr='title')
def准备(自身、obj):
准备好的数据['result_title_sort_s']#注意“_s”

以上内容将在名为
result\u title\u sort\u s
的文档中创建一个动态字符串字段,您可以通过该字段对结果进行排序。

仅根据已接受的答案,我发现简单地对要排序的文本使用FaceCharField而不是CharField就足以将其作为字符串输出到模式中,从而使其可排序


我对haystack/Solr相当陌生,所以我不确定使用FacetCharField的其他含义,但这对我来说很有效

虽然我发现了一个使用纯Hackstack代码(张贴在下面)的解决方案/黑客,但我喜欢你的解决方案,因为它不涉及黑客。标记作为答案!我考虑过为Haystack源代码做贡献,并添加另一种类型,它将以字符串的形式出现,但我意识到Haystack的目的是有限的,因此它可以是搜索引擎不可知的,这实际上只是SOLR的一个特殊性。所以我认为最好将补丁应用到模式中。我仍然认为讨论这个用例对haystack开发人员是有用的。他们可能会提出一个不可知论的解决方案。至少他们应该知道现实世界的问题,这样他们才能改进它。这一点很好。有人已经记录了这个:+1查看haystack中的solr_后端代码,似乎这个解决方案是设计的。
def format_text_for_sort(sort_term,remove_articles=False):
    ''' processes text for sorting field:
        * converts non-ASCII characters to ASCII equivalents
        * converts to lowercase
        * (optional) remove leading a/the
        * removes outside spaces
    '''
    sort_term = unidecode(sort_term).lower().strip()
    if remove_articles:
        sort_term =  re.sub(r'^(a\s+|the\s+)', '', sort_term )
    return sort_term
def prepare_result_title_sort(self,obj):
    return format_text_for_sort( obj.title, remove_articles=True )
result_title_sort = CharField(indexed=True, faceted=True)

def prepare_result_title_sort(self, article):
    return slugify(article.title.lower())
results = results.order_by('result_title_sort_exact')