2015-04-17 4 views
4

У меня проблемы сортировки по строковым полям в Lucene 5.0. Очевидно, способ, которым можно сортировать, поскольку Lucene 4 изменился. Ниже показан фрагмент некоторых полей, которые являются индексами для моих документов.Сортировка Строковое поле по алфавиту в 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' (expected = SORTED). Используйте UninvertingReader или index с docvalues.

Как я могу индексировать поле строки, чтобы иметь возможность сортировать его по алфавиту (используя поля сортировки) в Lucene 5? Любые примеры кода или фрагменты будут многозначны.

Поиск по релевантности работает очень хорошо, но когда пользователи вводят пустые поисковые запросы, все результаты имеют одинаковую актуальность. С этими вопросами я предпочитаю сортировать по названиям результатов, что вызывает проблемы в этой итерации Lucene.

ответ

7

Примечание: легче понять ошибки (как для себя, так и для людей, которых вы спрашиваете), если вы попытаетесь сварить это до наименьшего примера, который вы можете вначале. Вместо того, чтобы разобраться в вашей архитектуре, и классы не имеют доступа или ничего знать о, и такое, что я буду решения проблемы, воспроизведенный этим:

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)); 

Лучший подход к сортировке полей здесь, вероятно, будет заключаться в том, чтобы советоваться с docvalues. Добавление DocValues ​​в поле по существу индексирует его для сортировки и гораздо более эффективно использует типичный метод сортировки в Lucene 4.X, как я понимаю. Добавление как типичный TextField и SortedDocValuesField к тому же поля (имя), кажется, работает достаточно хорошо, и поддерживает поиск и сортировку с таким же названием поля:

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

0

Хотя индексирование использовать это для сортировки в 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); 
Смежные вопросы