Sortiing字符串字段按字母顺序在Lucene的5.0

问题描述:

我有在Lucene的5.0字符串字段排序的问题。从Lucene 4发生变化以来,您可以对其进行排序。下面显示了我的文档索引中的一些字段的片段。Sortiing字符串字段按字母顺序在Lucene的5.0

@Override 
public Document generateDocument(Process entity) 
{ 
    Document doc = new Document(); 
    doc.add(new IntField(id, entity.getID(), Field.Store.YES)); 
    doc.add(new TextField(title, entity.getProcessName(), Field.Store.YES)); 
    doc.add(new IntField(organizationID, entity.getOrganizationID(), Field.Store.YES)); 
    doc.add(new StringField(versionDate, DateTools.dateToString(entity.getVersionDate(), DateTools.Resolution.SECOND), Field.Store.YES)); 
    doc.add(new LongField(entityDate, entity.getVersionDate().getTime(), Field.Store.YES)); 
    return doc; 
} 

我想首先排序相关性,这工作得很好。我遇到的问题是在标题字段排序不起作用。我创建了一个sortfield,我试图在一系列方法调用之后使用TopFieldCollector。

public BaseSearchCore<Process, ProcessSearchResultScore>.SearchContainer search(String searchQuery, Filter filter, int page, int hitsPerPage) throws IOException, ParseException 
    { 
    SortField titleSort = new SortField(title, SortField.Type.STRING, true); 
    return super.search(searchQuery, filter, page, hitsPerPage, title); 
    } 

都到:

public SearchContainer search(String searchQuery, Filter filter, int page, int hitsPerPage, SortField... sortfields) throws IOException, ParseException 
    { 
     Query query = getQuery(searchQuery); 
     TopFieldCollector paginate = getCollector(sortfields); 
     int startIndex = (page -1) * hitsPerPage; 
     ScoreDoc[] hits = executeSearch(query, paginate, filter, startIndex, hitsPerPage); 

     return collectResults(query, filter, hitsPerPage, hits, page); 
    } 

终于到适用排序字段的方法:

private TopFieldCollector getCollector(SortField sortfield) throws IOException 
    { 
     SortField[] sortFields = new SortField[] {SortField.FIELD_SCORE, sortField}; 
     Sort sorter = new Sort(sortFields); 
     TopFieldCollector collector = TopFieldCollector.create(sorter, 25000, true, false, true); 
     return collector; 
    } 

使用返回收集器进行定期查询,结果是回。但是,如果我尝试使用此SortField进行排序,我会得到以下异常:

java.lang.IllegalStateException:意外的docvalues类型为NONE,用于字段'title'(预期= SORTED)。使用UninvertingReader或索引与文档值。

我应该如何索引一个字符串字段,以便能够(使用sortfields)在Lucene的5字母顺序排序呢?任何代码示例或代码片段都会非常流行。

按相关搜索工作得很好,但是当用户输入空搜索查询的所有结果具有相同的相关性。对于这些查询,我宁愿按结果标题进行排序,这会导致Lucene的迭代中出现问题。

的说明:这是比较容易的方式找出错误(既为自己和你问的人),如果你尝试煮到最小的例子,你可以先。而不是通过整理你的架构和类我没有访问或一无所知,而这样,通过以此为转载,我会解决这个问题:

Sort sort = new Sort(new SortField("title", SortField.Type.STRING)); 
TopDocs docs = searcher.search(new TermQuery(new Term("title", "something")), 10, sort); 

当标题的定义是这样的:

doc.add(new TextField("title", term, Field.Store.YES)); 

这里排序字段的最佳方法可能是采取关于文档值的建议。据我所知,将DocValue添加到字段本质上是将其编入索引以进行排序,并且在Lucene 4.X中的典型排序方法效率更高。添加这两种典型的TextFieldSortedDocValuesField相同的字段(名称)似乎工作相当好,并且支持搜索和使用相同的字段名称排序:

doc.add(new TextField("title", term, Field.Store.YES)); 
doc.add(new SortedDocValuesField("title", new BytesRef(term))); 
+0

感谢您的输入,你一下有关的方式,正确的意见我构造的前述的真正的问题。我标志着答案正确的,因为我也来使用SortedDocValuesField与我想排序居然能排序字段的结论。谢谢您的帮助! – Muppenz

+0

@femtoRgon是否可以为“title”创建单个字段而不是两个单独的字段,即使这意味着要创建自定义字段? –

+1

@BasilMusa - 对于所有的意图和目的,这正是它所做的。就自定义字段来说,如果它被分析了,你可能会遇到问题,否则你需要的所有东西都在['FieldType']中(https://lucene.apache.org/core/5_3_1/core/org/apache /lucene/document/FieldType.html)。 – femtoRgon

虽然索引使用在Lucene的5.0排序和以上:

doc.add(new SortedDocValuesField("title", new BytesRef(term))); 

搜索使用:

Sort sort = new Sort(); 
sort.setSort(new SortField("title", SortField.Type.STRING));    
TopDocs hits = searcher.search(bQuery.build(), pageSize, sort);