【问题标题】:Java, Lucene : Sort search results with highest hit rate.Java, Lucene : 对命中率最高的搜索结果进行排序。
【发布时间】:2017-07-04 08:56:02
【问题描述】:

我正在开发一个 Spring-MVC 应用程序,我在其中保存用户数据的内容并使用 Lucene 进行索引和搜索。目前该功能运行良好。 是否可以先对匹配概率最高的结果进行排序?我目前正在索引中保存段落或更多文本。谢谢。

保存代码:

 Directory directory = org.apache.lucene.store.FSDirectory.open(path);
            IndexWriterConfig config = new IndexWriterConfig(new SimpleAnalyzer());
            IndexWriter indexWriter = new IndexWriter(directory, config);
            indexWriter.commit();
            org.apache.lucene.document.Document doc = new org.apache.lucene.document.Document();
            if (filePath != null) {
                File file = new File(filePath); // current directory
                doc.add(new TextField("path", file.getPath(), Field.Store.YES));
            }
            doc.add(new StringField("id", String.valueOf(objectId), Field.Store.YES));
FieldType fieldType = new FieldType(TextField.TYPE_STORED);
                fieldType.setTokenized(false);
                if(groupNotes!=null) {
                    doc.add(new Field("contents", text + "\n" + tagFileName+"\n"+String.valueOf(groupNotes.getNoteNumber()), fieldType));
                }else {
                    doc.add(new Field("contents", text + "\n" + tagFileName, fieldType));
                }

搜索代码:

File file = new File(path.toString());
                if ((file.isDirectory()) && (file.list().length > 0)) {
                    if(text.contains(" ")) {
                        String[] textArray = text.split(" ");
                        for(String str : textArray) {
                            Directory directory = FSDirectory.open(path);
                            IndexReader indexReader = DirectoryReader.open(directory);
                            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
                            Query query = new WildcardQuery(new Term("contents","*"+str + "*"));
                            TopDocs topDocs = indexSearcher.search(query, 100);

                            for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
                                System.out.println("Score is "+scoreDoc.score);
                                org.apache.lucene.document.Document document = indexSearcher.doc(scoreDoc.doc);
                                objectIds.add(Integer.valueOf(document.get("id")));
                            }
                            indexSearcher.getIndexReader().close();
                            directory.close();
                        }
                    }
}
}

谢谢。

【问题讨论】:

  • 您使用 lucene 的方式似乎不对,这里您似乎没有标记您的内容,然后您使用了通配符查询(分数不可能很好)。这是错误的,您应该标记您的数据(使用 TextField 而不是 StringField)。我强烈建议按照教程了解基础知识。另请注意,直接使用lucene非常困难,您应该考虑使用elasticsearch或solr。
  • @nomoa 使用 lucene 很困难,但如果您能够使用 solr 或 elasticsearch,它确实取决于您的设计和架构决策。

标签: java lucene


【解决方案1】:

你的问题对我来说不是很清楚,所以下面只是猜测的答案,

  1. IndexSearcher 中有以org.apache.lucene.search.Sort 为参数的方法,

    public TopFieldDocs search(Query query, int n, Sort sort, boolean doDocScores, boolean doMaxScore) throws IOException 或

    public TopFieldDocs search(Query query, int n, Sort sort) throws IOException

    看看这些方法能否解决您的问题。

  2. 如果您只是想根据分数进行排序,那么不仅要收集文档 ID,还要在具有该分数字段的 pojo 中收集分数。

    在一些List 中收集所有这些pojo,然后在基础上进行外部循环排序列表 的分数。

for (ScoreDoc hit : hits) { //additional code pojo.setScore(hit.score);

    list.add(pojo);

   }

然后在for循环之外,

list.sort((POJO p1, POJO p2) -> p2 .getScore().compareTo(p1.getScore()));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2011-10-16
    • 2011-09-01
    相关资源
    最近更新 更多