Числовая сортировка в ручном (устаревшем) индексе в Neo4j 3 работает неправильно


Я использую устаревшее индексирование (теперь называемое ручным индексированием). После перехода с Neo4j 2 на версию 3 у меня возникли некоторые проблемы с числовой сортировкой.

Пример правильного утверждения в Neo4j 2:

queryContext.sort(new Sort(new SortField(AGE, SortField.INT, false)));

Это положение следует изменить для Neo4j 3 (Lucene 5):

queryContext.sort(new Sort(new SortField(AGE, SortField.Type.INT, false)));

Но если вы используете этот оператор сортировки, вы получите исключение:

java.lang.IllegalStateException: unexpected docvalues type SORTED_SET for field 'firstName' (expected=SORTED). Use UninvertingReader or index with docvalues.
at org.apache.lucene.index.DocValues.checkField(DocValues.java:208)
at org.apache.lucene.index.DocValues.getSorted(DocValues.java:264)
at org.apache.lucene.search.FieldComparator$TermOrdValComparator.getSortedDocValues(FieldComparator.java:762)
at org.apache.lucene.search.FieldComparator$TermOrdValComparator.getLeafComparator(FieldComparator.java:767)
at org.apache.lucene.search.FieldValueHitQueue.getComparators(FieldValueHitQueue.java:183)
at org.apache.lucene.search.TopFieldCollector$SimpleFieldCollector.getLeafCollector(TopFieldCollector.java:164)
at org.neo4j.kernel.api.impl.index.collector.DocValuesCollector.replayTo(DocValuesCollector.java:297)
at org.neo4j.kernel.api.impl.index.collector.DocValuesCollector.getTopDocs(DocValuesCollector.java:275)
at org.neo4j.kernel.api.impl.index.collector.DocValuesCollector.getIndexHits(DocValuesCollector.java:150)
at org.neo4j.index.impl.lucene.legacy.LuceneLegacyIndex.search(LuceneLegacyIndex.java:346)
at org.neo4j.index.impl.lucene.legacy.LuceneLegacyIndex.query(LuceneLegacyIndex.java:261)
at org.neo4j.index.impl.lucene.legacy.LuceneLegacyIndex.query(LuceneLegacyIndex.java:205)
at org.neo4j.index.impl.lucene.legacy.LuceneLegacyIndex.query(LuceneLegacyIndex.java:217)
at org.neo4j.kernel.impl.api.StateHandlingStatementOperations.nodeLegacyIndexQuery(StateHandlingStatementOperations.java:1440)
at org.neo4j.kernel.impl.api.OperationsFacade.nodeLegacyIndexQuery(OperationsFacade.java:1162)
at org.neo4j.kernel.impl.coreapi.LegacyIndexProxy$Type$1.query(LegacyIndexProxy.java:83)
at org.neo4j.kernel.impl.coreapi.LegacyIndexProxy.query(LegacyIndexProxy.java:365)

Я думаю, что это вызвано новым добавленным оператором в классе Neo4j indexer (Neo4j-поле индексирования для автоматической сортировки сейчас?). Смотрите в:

org.neo4j.index.impl.lucene.legacy.IndexType CustomType addToDocument( Document document, String key, Object value )

Новая строка:

document.add( instantiateSortField( key, value ) );

И метод instantiateSortField создает SortedSetDocValuesField

Поэтому я изменил свой код на:

queryContext.sort(new Sort(new SortedSetSortField(AGE, false)));

Это работает нормально, но сортировка не работает, потому что числа сортируются как строка. Я вижу, что параметр "value "является строкой каждый раз в методе"addToDocument". Я думаю, что первопричина объясняется этим старым комментарием:

see comment in class org.neo4j.index.impl.lucene.legacy.IndexType CustomType
// TODO We should honor ValueContext instead of doing value.toString() here.
// if changing it, also change #get to honor ValueContext.

Я пропустил какой-то новый способ индексирования, поиска и сортировки данных в Neo4j 3 или это действительно проблема в том, что значения индексируются как строка в Neo4j?

Простой модульный тест для Neo4j 2 и Neo4j 3 можно загрузить

1 2

1 ответ:

Решение, добавленное Мишадемьяненко в GH issue