Sitecore 7:按字段排序Lucene结果

4

我们正在尝试按标题字段对Lucene结果进行排序。

根据我对Lucene的理解,这需要将该字段设置为NOT_ANALYZED。

从论坛上的阅读中得知,这还要求我们使用LowerCaseKeywordAnalyzer。(此处

我无法想象如何将它们结合在一起,这是我现在的情况,但排序无法正常工作:

在Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration中:

<fields hint="raw:AddCustomField">
  <!--...-->
  <field luceneName="titleForSorting"     storageType="yes" indexType="untokenized">Title</field>
</fields>

我们的搜索结果类:
public class ContentSearchResultItem : SearchResultItem
{
    public virtual string Title { get; set; }

    [IndexField("titleForSorting")] 
    public virtual string TitleForSorting { get; set; }
}

我们的搜索实现:
using (var context = ContentSearchManager.GetIndex(Context.Indexname).CreateSearchContext())
{
    var query = context.GetQueryable<ContentSearchResultItem>()
        .Where(x => x.Title == "New York")
        .OrderBy(x => x.TitleForSorting);

    var searchResult = query.GetResults();
    var hitsQuery = searchResult.Hits;

    // Or sort here ??
    // hitsQuery = hitsQuery.OrderBy(x => x.Document.TitleForSorting);

    var results = hitsResults.Select(x => x.Document).ToArray();
}

正如所说,我也阅读了应该使用LowerCaseKeywordAnalyzer。但是无法弄清在哪里进行配置。 <luceneQueryParser> 似乎没有提供任何添加选项的地方。
欢迎任何帮助,谢谢!
2个回答

4

您说得对,如果您要进行排序,则最好不要将字段标记化,因为如果存在空格等字符,它会将其分解为小标记并在这些标记上进行排序。

您可以在fieldMap部分的field元素的子级中指定自定义分析器,例如:

<fieldNames hint="raw:AddFieldByFieldName">
   <field fieldName="titleForSorting" storageType="YES" indexType="UN_TOKENIZED"    vectorType="NO" boost="1f" type="System.String" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider">
       <analyzer type="Sitecore.ContentSearch.LuceneProvider.Analyzers.LowerCaseKeywordAnalyzer, Sitecore.ContentSearch.LuceneProvider" />
   </field>
   ...
</fields>

(此为 Sitecore 7.0 rev. 130918 版本的有效内容)

谢谢您的回答。我已经尝试过这个方法,但是在ContentSearchManager.GetIndex(Context.Indexname).CreateSearchContext()上出现了NullReferenceException异常。TitleForSorting实际上不是Sitecore中的字段,而是我在raw:AddCustomField部分手动添加的字段。 - Bertvan
你是否同时拥有fieldMap条目和自定义字段条目?如果没有,请尝试同时拥有它们,因为fieldMap在索引时应该会给出分析器提示。 - Stephen Pope
是的。但我现在明白了:NullRef异常是因为我简化了fieldNames部分下的字段输入。现在,我正在使用您的示例,该异常已经消失了。然而,排序仍然不起作用... - Bertvan
此外,在重新索引之后,使用Luke检查时,titleforsorting字段的术语未被转换为小写。因此,问题可能源于此处。 - Bertvan
1
有没有一种方法可以使用自定义的Lucene字段名称来实现这个?我正在尝试按“标题”排序,该标题已经被索引分词化,我不想更改它。我最好能够添加一个新的未分词字段,称为“title_for_sort”或其他类似的名称。 - NeilD
显示剩余3条评论

1

对于我来说有效的方法是在 where 子句之后添加.ToList

var query = context.GetQueryable<ContentSearchResultItem>()
        .Where(x => x.Title == "New York")
        .ToList()
        .OrderBy(x => x.TitleForSorting);

2
确实,您对搜索查询的排序应始终发生在查询而非结果堆栈上。将其放置在GetResults调用之前会将排序传递给搜索索引,从而确保在返回结果之前进行排序。在之后进行排序只是对您获得的结果进行排序。在这种情况下,要对所有内容进行排序的唯一方法是获取所有内容,这会极大地影响性能。 - Daved

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接