编辑我原来的问题,以更好地陈述我正在与之斗争的内容。这是我的问题域名。我在一家软件公司的测试部门工作。我们编写groovy脚本来测试软件。该软件使用包含键值对的属性文件来记录它所记录的警告和错误消息。
我想要做的是索引我所有的groovy脚本(当时300多个),然后遍历我的属性文件并检查我的哪些脚本正在检查该特定错误消息。
属性文件的示例:
B_C_Patched=Patched
这只是一个字符串对,其中有超过3000个。
以下是我为此编写的索引器类:
import org.apache.lucene.analysis.Analyzer
import org.apache.lucene.analysis.core.WhitespaceAnalyzer
import org.apache.lucene.document.Document
import org.apache.lucene.document.Field
import org.apache.lucene.document.StringField
import org.apache.lucene.index.IndexReader
import org.apache.lucene.index.IndexWriter
import org.apache.lucene.index.IndexWriterConfig
import org.apache.lucene.index.Term
import org.apache.lucene.search.IndexSearcher
import org.apache.lucene.search.ScoreDoc
import org.apache.lucene.search.TermQuery
import org.apache.lucene.store.RAMDirectory
import org.apache.lucene.util.Version
import org.apache.lucene.search.RegexpQuery
public class Indexer {
private final Config config
private final String SCRIPT_PATH = "path"
private final String CONTENTS = "contents"
//Store the index in memory
private final RAMDirectory idx = new RAMDirectory()
def Analyzer analyzer = new WhitespaceAnalyzer(Version.LUCENE_48)
public Indexer(Config config) {
this.config = config;
}
//Save index to Memory
public indexScripts() {
IndexWriterConfig idxConfig = new IndexWriterConfig(Version.LUCENE_48, analyzer)
IndexWriter iwriter = new IndexWriter(idx, idxConfig)
//Traverse the folder and index both the file path and its contents
config.getScriptFolder().traverse { file ->
if (file.isFile()) {
Document doc = new Document()
String path = file.name
Field pathField = new StringField(SCRIPT_PATH, path, Field.Store.YES)
doc.add(pathField)
String content = file.text
doc.add(new StringField(CONTENTS, content, Field.Store.YES))
println("Added file: " + file.name)
iwriter.addDocument(doc)
}
}
iwriter.close()
}
public ArrayList<String> searchIndex(String checkFor, boolean regEx = false) {
//Open a reader to the index in memory
def IndexReader indexReader = IndexReader.open(idx)
def IndexSearcher indexSearcher = new IndexSearcher(indexReader)
def ArrayList<String> results = new ArrayList<String>()
//Parse the query according to the string provided
if (!regEx) {
TermQuery query = new TermQuery(new Term(CONTENTS, checkFor))
println query
ScoreDoc[] hits = indexSearcher.search(query, 400).scoreDocs
if (hits.length > 0) {
for (int i = 0; i < hits.length; i++) {
def Document hitDoc = indexSearcher.doc(hits[i].doc)
results.add(hitDoc.get(SCRIPT_PATH))
return results
}
}
results = []
return results
} else {
RegexpQuery query = new RegexpQuery(new Term(checkFor))
ScoreDoc[] hits = indexSearcher.search(query, null, 400).scoreDocs
if (hits.size() != null) {
for (int i = 0; i < hits.length; i++) {
def Document hitDoc = indexSearcher.doc(hits[i].doc)
results.add(hitDoc.get(SCRIPT_PATH))
return results
}
}
results = []
return results
}
indexReader.close()
}
}
上面的代码给出了0结果。我希望它与字符串的B_C_Patched部分完全匹配,所以我将字符串拆分为“=”并将第一部分保存为checkFor变量。
我已经厌倦了不同的分析器查询解析器并且都返回0。
请帮助;)
答案 0 :(得分:0)
我的猜测:您正在使用StandardAnalyzer
(使用StandardTokenizer
)。后者使用Unicode word boundaries分割单词。你的字符串中的下划线(B_C_Patched
)有几个。
因此,当您对此进行索引时,它会分为B
,C
和Patched
。但是当您使用TermQuery
构建查询时,它不会对其进行分析并将其视为一个术语。要解决此问题,请使用QueryParser
并将其与contents:B_C_Patched
一起提供 - 返回的查询应该会产生不同的结果。