Lucene搜索引擎不准确,无法找出原因

时间:2015-12-16 20:04:52

标签: java search lucene search-engine

我正在尝试首次创建搜索引擎,并且我正在使用Apache Lucene提供的库。一切都很好,但是当我搜索多个单词时,例如"计算机科学"我得到的结果并不准确,因为我从来没有得到包含这两个词的文档。它分别在文档中搜索每个单词(我得到的文档包含"计算机"或"科学"但从不两者都有)。

我已经盯着我的代码差不多一个星期了,我无法弄清楚问题。查询解析似乎工作得很好,所以我认为问题可能出在搜索中,但我不知道自己做错了什么。所以,如果你能帮助我,我将感激不尽。

    public static wikiPage[] index(String searchQuery) throws SQLException, IOException, ParseException {

    String sql = "select * from Record";
    ResultSet rs = db.runSql(sql);

    StandardAnalyzer analyzer = new StandardAnalyzer();
    Directory index = new RAMDirectory();
    IndexWriterConfig config = new IndexWriterConfig(analyzer);

    //1. Indexer
    try (IndexWriter w = new IndexWriter(index, config)) {
        while (rs.next()) {
            String RecordID = rs.getString("RecordID");
            String URL = rs.getString("URL");
            String Title = rs.getString("Title");
            String Info = rs.getString("Info");

            addDoc(w, RecordID, URL, Info, Title);
        }

    } 
    catch (Exception e) {
        System.out.print(e);
        index.close();
    }

     //2. Query
    MultiFieldQueryParser multipleQueryParser = new MultiFieldQueryParser(new String[]{"Title", "Info"}, new StandardAnalyzer());
    Query q = multipleQueryParser.parse(searchQuery);


    //3. Search
    IndexReader reader = DirectoryReader.open(index);
    IndexSearcher searcher = new IndexSearcher(reader);
    TopDocs results = searcher.search(q, 10000);
    ScoreDoc[] hits = results.scoreDocs;


    // 4. display results
    wikiPage[] resultArray = new wikiPage[hits.length];
    System.out.println("Found " + hits.length + " hits.");
    for (int i = 0; i < hits.length; ++i) {
        int docId = hits[i].doc;
        Document d = searcher.doc(docId);
        resultArray[i] = new wikiPage(d.get("URL"), d.get("Title"));
        System.out.println((i + 1) + ". " + d.get("Title") + "\t" + d.get("URL"));
    }
    reader.close();
    return resultArray;
}

    private static void addDoc(IndexWriter w, String RecordID, String URL, String Info, String Title) throws IOException {
    Document doc = new Document();
    doc.add(new StringField("RecordID", RecordID, Field.Store.YES));
    doc.add(new TextField("Title", Title, Field.Store.YES));
    doc.add(new TextField("URL", URL, Field.Store.YES));
    doc.add(new TextField("Info", Info, Field.Store.YES));

    w.addDocument(doc);

}

这是 System.out.println(q.toString())的输出;

  (Title:computer Info:computer) (Title:science Info:science)

2 个答案:

答案 0 :(得分:1)

如果您想将其作为短语进行搜索(即找到“计算机”和“科学”一起),请使用引号括起查询,因此它应该看起来像"computer science" 。在您的代码中,您可以执行以下操作:

Query q = multipleQueryParser.parse("\"" + searchQuery + "\"");

如果您只想查找文档中包含某处的文档但不一定在一起的文档,则查询应该看起来像+computer +science。可能最简单的方法是更改​​查询解析器的默认运算符:

multipleQueryParser.setDefaultOperator(QueryParser.Operator.AND);
Query q = multipleQueryParser.parse(searchQuery);

答案 1 :(得分:-1)

根据文档,使用+前缀所需的条款,并使用AND(和OR以提高可读性。)

试试这个:

(Title:+computer OR Info:+computer) AND (Title:+science OR Info:+science)

也许建立这个字符串并直接使用它。