按ravendb中的自定义类型排序

时间:2016-09-09 21:38:02

标签: ravendb

我有这个班级

class MyType{
    public System.Version Version { get; set; }
}

我有一个json转换器,使用VersionstringVersion.Parse转换为Version.ToString()。所以我的文档是这样的:

{
    "version": "1.0.0"
}

现在,我想按该字段排序,我不想要默认的词典排序,我想使用System.Version

我试过这个:

    public override IndexDefinition CreateIndexDefinition()
    {
        return new IndexDefinition
        {
            Map = "from q in docs.MyTypes select new { Version = Version.Parse(q.Version) }",
            SortOptions = {
                { "Version", SortOptions.Custom }
            }
        };
    }

但我得到一个例外:

System.NullReferenceException: Object reference not set to an instance of an object.
at Lucene.Net.Search.SortField.GetComparator(Int32 numHits, Int32 sortPos)
at Lucene.Net.Search.FieldValueHitQueue.OneComparatorFieldValueHitQueue..ctor(SortField[] fields, Int32 size)
at Lucene.Net.Search.FieldValueHitQueue.Create(SortField[] fields, Int32 size)
at Lucene.Net.Search.TopFieldCollector.Create(Sort sort, Int32 numHits, Boolean fillFields, Boolean trackDocScores, Boolean trackMaxScore, Boolean docsScoredInOrder)
at Lucene.Net.Search.IndexSearcher.Search(Weight weight, Filter filter, Int32 nDocs, Sort sort, Boolean fillFields)
at Lucene.Net.Search.IndexSearcher.Search(Weight weight, Filter filter, Int32 nDocs, Sort sort)

还有其他办法吗?或者这个代码可以修复吗?

编辑(解决方案)

作为suggested by ayende我们最终得到了这段代码:

public class SortByVersionIndex<T> : AbstractIndexCreationTask<T>
    where T : IVersionable
{
    public SortByVersionIndex()
    {
        Map = xs => from x in xs
                    let v = Version.Parse(x.Version.ToString())
                    select new
                    {
                        Version = v.Build + v.Minor * 1000 + v.Major * 100000
                    };

        Sort(x => x.Version, SortOptions.Long);
    }

    public override string IndexName => $"{typeof(T).Name}/SortByVersion";
}

我们需要像这样的索引用于多个集合,这就是为什么我们必须使它成为泛型并覆盖IndexName

Version.Parse(x.Version.ToString())是一种在c#中静态输入代码的方法,而x.Version是服务器上的字符串。

1 个答案:

答案 0 :(得分:0)

无法在RavenDB中提供自定义排序器。 Custom选项在那里,因为它是我们公开的Lucene功能的直接副本。 你可以做的是在索引时创建一个版本的实例,然后转换为long,然后进行比较。