我们正在使用Lucene进行代码内容搜索。我们使用自己的Custom Analyzer索引项目中的文件。我们在获取匹配文件的出现次数方面遇到了麻烦。
我们在搜索时使用 BooleanQuery (A phraseQuery with must子句)时,每个文件的确切出现次数。 现在我们又添加了另外两个查询,前一个查询类似于 BooleanQuery (带有must子句的A phraseQuery +带有must子句的A prefixQuery )。对于此查询,我们得到的匹配结果准确,但我们将每个文件的出现次数设置为2。 我们使用以下代码来获取出现次数
public class SearchTermFrequencyCollector implements Collector {
private IndexSearcher searcher;
private HashMap<String, Integer> result = new HashMap<String, Integer>();
public SearchTermFrequencyCollector(IndexSearcher searcher){
this.searcher=searcher;
}
public HashMap<String, Integer> getSearchTermFrequency(){
return result;
}
@Override
public boolean needsScores() {
return true;
}
@Override
public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
final int DOCID = context.docBase;
return new LeafCollector() {
Scorer scorer;
@Override
public void collect(int doc) throws IOException {
int numOccurrencess = scorer.freq();
LOGGER.log(Level.INFO,"DOC_ID ::: "+DOCID);
Document document = searcher.doc(DOCID+doc);
result.put(document.get(Constants.INDEX_FIELD_FILE_PATH), numOccurrencess);
}
@Override
public void setScorer(Scorer scorer) throws IOException {
this.scorer = scorer;
}
};
}
}
我们正在使用上面的类获取匹配的文件和以下代码。
indexReader = getIndexReader(indexDir);
msearcher = new IndexSearcher(indexReader);
SearchTermFrequencyCollector searchtermfreq = new SearchTermFrequencyCollector(msearcher);
msearcher.search(resultQuery, searchtermfreq);
HashMap<String, Integer> resultMap = searchtermfreq.getSearchTermFrequency();
searchDetails = new JSONObject(resultMap);
hits = resultMap.size();
resultDetails.put("hits", hits);
resultDetails.put(indexType, searchDetails);
对于查询,我们使用以下代码
searchString = searchString.toLowerCase();
QueryParser qp = new QueryParser(IndexConstants.INDEX_FIELD_CONTENT, CodeCustomAnalyzer.getdefaultInstance());
qp.setDefaultOperator(QueryParser.Operator.AND);
Query contentQuery = qp.createPhraseQuery(IndexConstants.INDEX_FIELD_CONTENT, searchString);
resultQuery.add(contentQuery, BooleanClause.Occur.MUST);
if (fileExtn.length() > 0) {
BooleanQuery.Builder ExtnQuery = new BooleanQuery.Builder();
for (int i = 0; i < fileExtn.length(); i++) {
String extn = fileExtn.getString(i);
Query extnQuery = new TermQuery(new Term(IndexConstants.INDEX_FIELD_FILE_EXTN, extn));
ExtnQuery.add(extnQuery, BooleanClause.Occur.SHOULD);
}
resultQuery.add(ExtnQuery.build(), BooleanClause.Occur.MUST);
}
Query filePathQuery = new PrefixQuery(new Term(IndexConstants.INDEX_FIELD_FILE_PATH, workingPaths));
resultQuery.add(filePathQuery, BooleanClause.Occur.MUST);
示例文档:
Doc1:
当罗马将军被出卖,他的家人被一位皇帝的腐败儿子谋杀时,他作为寻求报复的角斗士来到罗马。
搜索时
Roman General我在collect函数中得到scorer.freq()为2.但是只有一次出现。如果我只添加一个像contentquery这样的查询,而不是同时添加两个ExtnQuery,那么我将得到结果,即出现的结果,即1次出现。