<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">OpenGrok默认会将*.o *.so这些二进制文件也加入索引(其实没什么坏处),如果想在查询时过滤这些文件,怎么做?</span>
要点:
https://github.com/OpenGrok/OpenGrok/blob/master/src/org/opensolaris/opengrok/index/IgnoredNames.java
IgnoredNames是默认的索引过滤,对文件路径做字符串匹配。
https://github.com/OpenGrok/OpenGrok/blob/master/src/org/opensolaris/opengrok/search/SearchEngine.java
可对这里的searchSingleDatabase和searchMultiDatabase做修改。
private void searchSingleDatabase(File root, boolean paging) throws IOException { IndexReader ireader = DirectoryReader.open(FSDirectory.open(root)); searcher = new IndexSearcher(ireader); collector = TopScoreDocCollector.create(hitsPerPage * cachePages, docsScoredInOrder); searcher.search(query, collector); totalHits = collector.getTotalHits(); if (!paging && totalHits > 0) { collector = TopScoreDocCollector.create(totalHits, docsScoredInOrder); searcher.search(query, collector); } hits = collector.topDocs().scoreDocs; for (ScoreDoc hit : hits) { int docId = hit.doc; Document d = searcher.doc(docId); docs.add(d); } }
注意,这里有2个修改点:修改collector的实现,使得如果文件名后缀是*.so *.o时就不collect;或者修改Document add的条件判断。
修改collector不可行,因为TopScoreDocCollector是Lucene的类,而我只想改改OpenGrok。修改Document add的条件判断较为方便,问题是:如何从Document对象获得“文件名的后缀”这一信息?
在org/opensolaris/opengrok/search包中找不到线索,看看index索引模块。
https://github.com/OpenGrok/OpenGrok/blob/master/src/org/opensolaris/opengrok/index/IndexDatabase.java
Document doc = searcher.doc(top.scoreDocs[0].doc); String foundPath = doc.get(QueryBuilder.PATH);
/** * Fields we use in lucene public ones */ public static final String FULL = "full"; public static final String DEFS = "defs"; public static final String REFS = "refs"; public static final String PATH = "path"; public static final String HIST = "hist"; public static final String TYPE = "type";没有。这里hist字段不知道是什么意思。
https://lucene.apache.org/core/4_0_0/core/org/apache/lucene/search/FieldValueFilter.html
https://lucene.apache.org/core/4_0_0/core/org/apache/lucene/search/FieldCacheTermsFilter.html
具体怎么做,没时间研究了。内置的filter类似乎是includes语义,不是excludes语义,所以可能还需要提供自己的定制实现。