我有一些带有文本和计数两个字段的文档。
我已经使用Lucene
对这些文档进行了索引,现在我想要通过文本搜索并按照计数倒序排序来获取结果。如何实现?
Apache Lucene的默认搜索实现返回按分数排序的结果(最相关的结果第一),然后按id排序(最旧的结果第一)。
这种行为可以在查询时使用一个额外的Sort参数进行自定义。
TopFieldDocs Searcher#search(Query query,Filter filter,int n,Sort sort)
Sort参数指定用于排序的字段或属性。默认实现是这样定义的:
new Sort(new SortField[] { SortField.FIELD_SCORE, SortField.FIELD_DOC });
要更改排序方式,您只需将字段替换为您想要的字段:
new Sort(new SortField[] {
SortField.FIELD_SCORE,
new SortField("field_1", SortField.STRING),
new SortField("field_2", SortField.STRING) });
这听起来很简单,但在满足以下条件之前将不起作用:
排序字段必须被索引而不被标记:
document.add (new Field ("byNumber", Integer.toString(x), Field.Store.NO, Field.Index.NOT_ANALYZED));
排序字段内容必须仅为纯文本。如果用于排序的字段中只有一个元素具有特殊字符或重音符号,则整个搜索将返回未排序的结果。
请参阅此教程。
以下代码可以实现排序功能。最后一个参数是boolean reverse
,如果将其设置为true,则会按照相反的顺序进行排序,即在您的情况下按降序排列。
SortField longSort = new SortedNumericSortField(FIELD_NAME_LONG, SortField.Type.LONG, true);
示例代码:
IndexSearcher searcher = new IndexSearcher(reader);
Query q = new MultiFieldQueryParser(new String[] { FIELD_NAME_NAME}, analyzer).parse("YOUR_QUERY") );
SortField longSort = new SortedNumericSortField(FIELD_NAME_LONG, SortField.Type.LONG, true);
Sort sort = new Sort(longSort);
ScoreDoc[] hits = searcher.search(q, 10 , sort).scoreDocs;
此外,在创建索引时,您需要将启用排序的字段添加为NumericDocValuesField
。
doc.add(new NumericDocValuesField(FIELD_NAME_LONG, longValue));//sort enabled field
首先:
Fieldable count = new NumericField("count", Store.YES, true);
SortField field = new SortField("count", SortField.INT);
Sort sort = new Sort(field);
TopFieldDocs docs = searcher.search(query, 20, sort);
ScoreDoc[] sds = docs.scoreDocs;
SortField.Type
中,因此对于字符串来说,它是SortField.Type.STRING
。 - dube