hangscer

lucene的简单demo

2018/09/23

Before

    lucene是基于java实现的信息检索工具类库。其工作原理大致是将非结构化的文本内容解析提取信息并从新组织内容,得到一定的相对结构的数据,在搜索时候,利用该相对结构化的数据进行搜索,从而提高效率。
    以下是简单的hello world级别的程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var directory = FSDirectory.open(Paths.get("/Users/jianghang/Coding/luceneTemp"))
//索引index放在哪里,也可以将其放置于内存中
val analyzer = new JcsegAnalyzer(JcsegTaskConfig.COMPLEX_MODE, new JcsegTaskConfig(true))
//使用哪种分词器,中文分词器有ik、paoding等等
val indexWriterConfig = new IndexWriterConfig(analyzer).setOpenMode(OpenMode.CREATE)
val indexWriter = new IndexWriter(directory, indexWriterConfig)
//使用indexWriter 写入document
val sourceFiles = Paths.get("/Users/jianghang/Desktop/blog/source/_posts").toFile.listFiles().toList
sourceFiles.foreach { file =>
Try {
val document = new Document()
document.add(new TextField("fileName", file.getName, Store.YES)) //文件名
document.add(new StoredField("fileSize", file.length()))
document.add(new StoredField("filePath", file.getPath))
document.add(new TextField("fileContent", Source.fromFile(file)(Codec.UTF8).getLines().toList.mkString, Store.YES))
println(file.getName)
document
/**
* 为每一个文件建立一个document,
* document中包含4个域(field)
* 对于TextField而言,域的值会被解析(分词)并为此建立index;
* 对于StoredField而言,域的值仅仅被存储,不会被解析分词也不会建立index。
* 如果该域的值被解析分词的话,那么该字段一定会被建立index
*/
}.map{doc =>
indexWriter.addDocument(doc)
//写入文档
}
}
indexWriter.close()
directory.close()



    以下是简单的查询demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
directory = FSDirectory.open(Paths.get("/Users/jianghang/Coding/luceneTemp"))
val indexReader = DirectoryReader.open(directory)
val indexSearcher = new IndexSearcher(indexReader)
val query = new TermQuery(new Term("fileName", "ensime"))
/**
* 利用Term可以对那些见了index的field进行搜索,条件:包含该字段
*/
val top10Docs = indexSearcher.search(query, 10)
top10Docs.scoreDocs.toList.foreach { item =>
val doc = indexSearcher.doc(item.doc)
println("fileName:" + doc.get("fileName"))
println(s"fileSize:${doc.get("fileSize").toLong}")
println(s"filePath:${doc.get("filePath")}")
}


1
2
3
4
5
6
7
8
val queryParser = new QueryParser("fileContent", new JcsegAnalyzer(JcsegTaskConfig.COMPLEX_MODE, new JcsegTaskConfig(true)))
indexSearcher.search(queryParser.parse("fileContent:安装 sbt 成功"), 10).scoreDocs.toList.foreach { scoreDoc =>
val doc = indexSearcher.doc(scoreDoc.doc)
println("fileName:" + doc.get("fileName"))
println(s"fileSize:${doc.get("fileSize").toLong}")
println(s"filePath:${doc.get("filePath")}")
}
indexReader.close()