Lucene 搜索引擎不准确,无法弄清楚原因
Lucene search engine isn't accurate, can't figure out why
我是第一次尝试创建搜索引擎,我使用的是 Apache Lucene 提供的库。一切正常,但是当我搜索多个词时,例如 "computer science",我得到的结果并不准确,因为我从来没有得到包含这两个词的文档。它分别搜索文档中的每个单词(我得到的文档包含 "computer" 或 "science" 但绝不会包含两者)。
我已经盯着我的代码看了将近一个星期了,但我无法找出问题所在。查询解析似乎运行良好,所以我认为问题可能出在搜索中,但我不知道自己做错了什么。所以如果你能帮助我,我将不胜感激。
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)
根据文档,在 required 术语前加上 +
并使用 AND
(和 OR
以提高可读性)。
试试这个:
(Title:+computer OR Info:+computer) AND (Title:+science OR Info:+science)
也许构建这个字符串并直接使用它。
如果您想将其作为词组进行搜索(即查找 "computer" 和 "science" 一起 ),请用引号将查询括起来,因此它应该看起来像 "computer science"
。在您的代码中,您可以执行以下操作:
Query q = multipleQueryParser.parse("\"" + searchQuery + "\"");
如果您只想在文档中的某处 查找同时包含两个词的文档,但不一定同时包含,则查询应类似于 +computer +science
。可能最简单的方法是更改查询解析器的默认运算符:
multipleQueryParser.setDefaultOperator(QueryParser.Operator.AND);
Query q = multipleQueryParser.parse(searchQuery);
我是第一次尝试创建搜索引擎,我使用的是 Apache Lucene 提供的库。一切正常,但是当我搜索多个词时,例如 "computer science",我得到的结果并不准确,因为我从来没有得到包含这两个词的文档。它分别搜索文档中的每个单词(我得到的文档包含 "computer" 或 "science" 但绝不会包含两者)。
我已经盯着我的代码看了将近一个星期了,但我无法找出问题所在。查询解析似乎运行良好,所以我认为问题可能出在搜索中,但我不知道自己做错了什么。所以如果你能帮助我,我将不胜感激。
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)
根据文档,在 required 术语前加上 +
并使用 AND
(和 OR
以提高可读性)。
试试这个:
(Title:+computer OR Info:+computer) AND (Title:+science OR Info:+science)
也许构建这个字符串并直接使用它。
如果您想将其作为词组进行搜索(即查找 "computer" 和 "science" 一起 ),请用引号将查询括起来,因此它应该看起来像 "computer science"
。在您的代码中,您可以执行以下操作:
Query q = multipleQueryParser.parse("\"" + searchQuery + "\"");
如果您只想在文档中的某处 查找同时包含两个词的文档,但不一定同时包含,则查询应类似于 +computer +science
。可能最简单的方法是更改查询解析器的默认运算符:
multipleQueryParser.setDefaultOperator(QueryParser.Operator.AND);
Query q = multipleQueryParser.parse(searchQuery);