Lucene学习-3(Lucene API详解)

Lucene API详解

前面已经讲了luncene的核心,但还有很多细节,也就是一些LuceneAPI使用,接下来一一讲解。

索引目录Directory

Directory是一个对索引目录的一个抽象。索引目录用于存放lucene索引文件。直接根据一个文件夹地址来创建索引目录使用SimpleFSDirectory。
MMapDirectory : 针对64系统,它在维护索引库时,会结合“内存”与硬盘同步来处理索引。
SimpleFS Directory : 传统的文件系统索引库。
RAMDirectory : 内存索引库

Document(行)及IndexableField(列)

在这里插入图片描述
当往索引中加入内容的时候,每一条信息用一个Document来表示,Document的意思表示文档,也可以理解成记录,与关系数据表中的一行数据记录类似;
IndexableField表示字段,与关系数据表中的列类似(列数量不定!!),每个Document也由一系列的IndexableField组成,可以理解为数据库的动态列;
在这里插入图片描述

Document提供的方法主要包括:
字段添加:add(Fieldable field)
字段删除:removeField、removeFields
获取字段或值:get、getBinaryValue、getField、getFields等

IndexableField及Field
Field代表Document中的一列数据,相当于一条表记录中的一列。
Lucene提供了一个接口IndexableField,其它的API大多针对这个接口编程,因此Lucene中的列对象实际上是由IndexableField来定义。在实际开发中,主要使用的是Field类的子类。
在这里插入图片描述
Field的Store方式及Index方式
Lucene中,在创建Field的时候,可以指定Field的store及index属性;
store属性:表示字段值是否存储,Store.YES表示要存储,而Store.NO则表示不存储;
index属性:表示字段的索引方式,
Tokenized表示根据设定的词法分析器来建立该字段的索引;FALSE,不分词;true要分词。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
索引库中实际分为两个部分,一个部分占的空间相对大一些叫做数据区,有Store属性维护,代表是否把字段的内容存到数据区;另一个部分相对小一些,叫做目录区,由Index维护,代表是否支持搜索。
Store和Index组合使用的适用情况见下图:
在这里插入图片描述
是否要创建索引: 看是否需要搜索。
是否要分词 : 看是否是专有名词。
是否要存储 : 结果页面,是否要显示,看文档字段的内容能不能链接找到。—大字段

分词Analyzer(词法分析器)

分词器是Lucene中非常重要的一个知识点,如果你面试时说你用过Lucene面试官一定会问你用的什么分词器。
分词,也称词法分析器(或者叫语言分析器),就是指索引中的内容按什么样的方式来建立,这在全文检索中非常关键,是按英文单词建立索引,还是按中文词意建立索引;这些需要由Analyzer来指定。
对于中文,需要采用字典分词,也叫词库分词;把中文件的词全部放置到一个词库中,按某种算法来维护词库内容;如果匹配到就切分出来成为词语。通常词库分词被认为是最理想的中文分词算法。如:“我们是中国人”,效果为:“我们”、“中国人”。(可以使用SmartChineseAnalyzer,“极易分词” MMAnalyzer ,或者是“庖丁分词”分词器、IKAnalyzer。推荐使用IKAnalyzer )
在这里我们推荐IKAnalyzer。使用时需导入IKAnalyzer.jar,并且拷贝IKAnalyzer.cfg.xml,ext_stopword.dic文件,分词器测试代码如下:

public class AnalyzerTest {
	//创建索引的数据 现在写死,以后根据实际应用场景
	private String en = "oh my lady gaga"; // oh my god
	private String cn = "迅雷不及掩耳盗铃儿响叮当仁不让";
	private String str = "源代码教育FullText Search Lucene框架的学习";
	
	
	/**
	 * 把特定字符串按特定的分词器来分词
	 * @param analyzer
	 * @param str
	 * @throws Exception
	 */
	public void testAnalyzer(Analyzer analyzer,String str) throws Exception {
		TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(str));
		// 在读取词元流后,需要先重置/重加载一次
		tokenStream.reset();
		while(tokenStream.incrementToken()){
			System.out.println(tokenStream);
		}
	}
	
	//标准分词:不支持中文
	@Test
	public void testStandardAnalyzer() throws Exception {
		
		testAnalyzer(new StandardAnalyzer(), cn);
	}
	
	//简单分词:不支持中文
	@Test
	public void testSimpleAnalyzer() throws Exception {
		testAnalyzer(new SimpleAnalyzer(), cn);
	}
	
	//二分分词:两个字是一个词
	@Test
	public void testCJKAnalyzer() throws Exception {
		testAnalyzer(new CJKAnalyzer(), cn);
	}
	
	//词典分词:从词典中查找
	@Test
	public void testSmartChineseAnalyzer() throws Exception {
		testAnalyzer(new SmartChineseAnalyzer(), str);
	}
	
	//IK分词:从词典中查找
	// 简单使用:拷贝两个配置文件,IKAnalyzer.cfg.xml,stopword.dic拷贝一个jar包 
    IKAnalyzer2012_V5.jar
	//       扩展词,停止词
	//  注意:打开方式,不要使用其他的,
	//直接使用eclipse的text Editor, 修改以后要刷新一下让项目重新编译(有时候需要有时候不需要刷新)	
	
	@Test
	public void testIKAnalyzer() throws Exception {
		//true 粗密度分词(智能分词)  false 细密度分词
		testAnalyzer(new IKAnalyzer(true), str);
	}
}

索引的添删改

经过之前的分析,我们知道对索引的操作统一使用IndexWriter。测试代码如下:

// 数据源
private String doc1 = "hello world";
private String doc2 = "hello java world";
private String doc3 = "hello lucene world";

// 索引库目录
private String indexPath = "F:\\ecworkspace\\lucene\\indexCRUD";
@Test
public void createIndex() throws IOException, ParseException {
	/**
	 * 准备工作
	 */
	// 索引目录
	Directory d = FSDirectory.open(Paths.get(indexPath));
	// 词法分析器
	Analyzer analyzer = new StandardAnalyzer();
	// 写操作核心配置对象
	IndexWriterConfig conf = new IndexWriterConfig(analyzer);
	conf.setOpenMode(OpenMode.CREATE);
	// 写操作核心对象
	IndexWriter indexWriter = new IndexWriter(d, conf);
	System.out.println(indexWriter);

	/**
	 * 操作
	 */
	Document document1 = new Document();
	document1.add(new TextField("id", "1", Store.YES));
	document1.add(new TextField("name", "doc1", Store.YES));
	document1.add(new TextField("content", doc1, Store.YES));
	indexWriter.addDocument(document1);

	Document document2 = new Document();
	document2.add(new TextField("id", "2", Store.YES));
	document2.add(new TextField("name", "doc2", Store.YES));
	document2.add(new TextField("content", doc2, Store.YES));
	indexWriter.addDocument(document2);
	Document document3 = new Document();
	document3.add(new TextField("id", "3", Store.YES));
	document3.add(new TextField("name", "doc3", Store.YES));
	document3.add(new TextField("content", doc3, Store.YES));
	indexWriter.addDocument(document3);
	/**
	 * 收尾
	 */
	indexWriter.commit();
	indexWriter.close();
	
	searchIndex();
}

@Test
public void del() throws IOException, ParseException{
	/**
	 * 准备工作
	 */
	// 索引目录
	Directory d = FSDirectory.open(Paths.get(indexPath));
	// 词法分析器
	Analyzer analyzer = new StandardAnalyzer();
	// 写操作核心配置对象
	IndexWriterConfig conf = new IndexWriterConfig(analyzer);
	// 写操作核心对象
	IndexWriter indexWriter = new IndexWriter(d, conf);
	System.out.println(indexWriter);
	
	
	//删除所有
	//indexWriter.deleteAll();
	//第一种
//	QueryParser qpParser = new QueryParser("id", analyzer);
//	Query query = qpParser.parse("1");
//	indexWriter.deleteDocuments(query);
	
	//第二种
	indexWriter.deleteDocuments(new Term("id", "1"));
	
	indexWriter.commit();
	indexWriter.close();
	
	searchIndex();
}
	
@Test
public void update() throws IOException, ParseException{
	/**
	 * 准备工作
	 */
	// 索引目录
	Directory d = FSDirectory.open(Paths.get(indexPath));
	// 词法分析器
	Analyzer analyzer = new StandardAnalyzer();
	// 写操作核心配置对象
	IndexWriterConfig conf = new IndexWriterConfig(analyzer);
	// 写操作核心对象
	IndexWriter indexWriter = new IndexWriter(d, conf);
	System.out.println(indexWriter);
	
	
	Document doc = new Document();
	doc.add(new TextField("id", "2", Store.YES));
	doc.add(new TextField("name", "doc2", Store.YES));
	doc.add(new TextField("content", "修改后 -的doc2", Store.YES));
	
	indexWriter.updateDocument(new Term("id","2"), doc );
	/*等价于
	 indexWriter.deleteDocuments(new Term("id", "2"));
	 indexWriter.addDocument(doc);
	 */
	indexWriter.commit();
	indexWriter.close();
	
	searchIndex();
}

@Test
public void searchIndex() throws IOException, ParseException {
	// 索引目录
	Directory d = FSDirectory.open(Paths.get(indexPath));
	// 词法分析器
	Analyzer analyzer = new StandardAnalyzer();
	// 创建索引的读写对象
	IndexReader r = DirectoryReader.open(d);
	// 创建核心对象
	IndexSearcher indexSearcher = new IndexSearcher(r);

	// 查询解析器
	// 参数1:默认查询的字段
	// 参数2:分词器
	QueryParser queryParser = new QueryParser("content", analyzer);
	String queryString = "*:*";

	Query query = queryParser.parse(queryString);
	// 调用核心对象的search方法
	// 参数query: 查询对象
	// 参数 n : 前n条
	TopDocs topDocs = indexSearcher.search(query, 50);
	System.out.println("一共查询到的数量:" + topDocs.totalHits);

	// 获得数据集合
	ScoreDoc[] scoreDocs = topDocs.scoreDocs;
	for (ScoreDoc scoreDoc : scoreDocs) {
		// 获取文档ID
		int docId = scoreDoc.doc;
		// 通过docId获取Document
		Document doc = indexSearcher.doc(docId);

		System.out.println("id="+doc.get("id")+",name=" + doc.get("name") + ",content=" + doc.get("content"));
	}
}

Query及Searcher

搜索是全文检索中最重要的一部分,前面HelloWorld中也发现,Query对象只是一个接口,他有很多子类的实现。在前面直接使用QueryParser的Parse方法来创建Query对象的实例,实际他会根据我们传入的搜索关键字自动解析成需要的查询类型,索引在这里我们也可以直接new一个Query实例来达到不同的搜索效

//抽取结构:
// 先做一个准备工作,提供两个search方法 
//一个传入搜索关键字进行搜索
public void search(String keyword) throws Exception {
	Directory directory = FSDirectory.open(Paths.get("E:\\tools\\eclipse\\workspace\\lucene\\helloIndex"));
	;
	// 索引的和读取对象
	IndexReader reader = DirectoryReader.open(directory);
	// 搜索文档通过核心搜索类IndexSearcher来查询
	IndexSearcher indexSearcher = new IndexSearcher(reader);

	// 先创建一个QueryParse对象
	QueryParser queryParser = new QueryParser("content", new StandardAnalyzer());
	// 通过queryParse对象解析关键字并创建对应的查询对象
	Query query = queryParser.parse(keyword);

	// 通过search方法返回前n个文档的封装对象
	TopDocs topDocs = indexSearcher.search(query, 5);
	// 总共找到的相关的文档数
	int totalHits = topDocs.totalHits;
	System.out.println("总条数:" + totalHits);
	// 获取查询的结果(并不包含文档本身)
	ScoreDoc[] scoreDocs = topDocs.scoreDocs;
	for (ScoreDoc scoreDoc : scoreDocs) {
		int documentId = scoreDoc.doc;
		Document document = indexSearcher.doc(documentId);
		float score = scoreDoc.score;

		// 获取文档的字段值
		String docId = document.get("docId");
		String content = document.get("content");

		System.out.println("ID:" + documentId + ",score:" + score + ",docId:" + docId + ",content:" + content);
	}
}
	
// 传入一个查询对象
public static void testSearch(Query q) throws Exception {
       // 索引库地址
	String path = "E:\\work\\eclipse4.7_project\\Luncene-demo\\index";
	System.out.println("对应的查询语句为:" + q);
	// 获取索引库的目录
	Directory d = FSDirectory.open(Paths.get(path));
	// 获取索引读取对象
	IndexReader reader = DirectoryReader.open(d);
	// 创建索引查询器
	IndexSearcher searcher = new IndexSearcher(reader);
	// 执行查询
	TopDocs td = searcher.search(q, 10);
	// 遍历结果
	for (int i = 0; i < td.scoreDocs.length; i++) {
		// 得到符合条件的内部文档对象
		ScoreDoc doc = td.scoreDocs[i];
		// 得到文档对象
		Document d1 = searcher.doc(doc.doc);
		System.out.println("title: " + d1.get("title") + "     content:" + d1.get("content"));
	}
}

1)单词查询
在这里插入图片描述
2)段落搜索 要想把多个单词当成一个整体进行搜索,使用双引号包裹
在这里插入图片描述
3)通配符搜索
在这里插入图片描述
4)模糊搜索 最多允许 2个错误
在这里插入图片描述
5)临近查询 在段落查询的基础上用“~”后面跟一个1到正无穷的正整数。代表段落中,单词与单词之间最大的间隔数
在这里插入图片描述
6)组合查询
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: lucene-core-4.9.0.jar是Lucene搜索引擎的核心库文件,它是一个用Java语言编写的开源软件,主要用于实现全文搜索和索引功能。 Lucene是一个高性能的全文搜索引擎库,它提供了一系列用于创建、更新和查询索引的API。对于需要在大量文本数据中进行快速和准确搜索的应用程序来说,Lucene是一个非常好的选择。 核心库文件lucene-core-4.9.0.jar包含了Lucene搜索引擎的所有核心功能,包括索引的创建和管理、搜索查询的执行、搜索结果的排序和过滤等。通过引入该库文件,开发人员可以在自己的应用程序中使用Lucene提供的功能来实现文本数据的全文索引和搜索。 在使用Lucene时,开发人员可以根据自己的需要,使用lucene-core-4.9.0.jar的API来创建索引,将文档进行分词、过滤和标准化处理,然后将处理后的文档添加到索引中。当需要进行搜索时,可以使用Lucene提供的查询语法和查询API,对索引中的文档进行高效的全文搜索。 除了lucene-core-4.9.0.jar之外,Lucene还提供了其他一些相关的jar文件,例如lucene-analyzers-common.jar和lucene-queryparser.jar等,它们可以用于分析和处理文本数据,以及解析查询语法。通过组合使用这些库文件,开发人员可以更灵活地构建自己的全文搜索应用程序。 总之,lucene-core-4.9.0.jar是Lucene搜索引擎的核心库文件,它提供了一系列用于创建、更新和查询文本数据索引的API,为开发人员提供了实现全文搜索功能的便利。 ### 回答2: lucene-core-4.9.0.jar是Lucene项目的核心库,它是用Java编写的全文搜索引擎库。Lucene是一个开源项目,旨在提供一个强大且高效的搜索引擎,用于构建各种应用程序,如网站搜索,文本分析和信息检索等。 lucene-core-4.9.0.jar提供了许多关键的功能和类,包括索引创建和管理,查询解析和执行,文本分析和词法处理等。通过使用这个库,开发人员可以轻松地构建自己的搜索应用程序,并实现快速和准确的搜索功能。 在Lucene的使用过程中,开发人员可以通过创建索引来处理需要搜索的文档集合。索引是一个用于快速查找和检索文档的数据结构,它包含了文档中的关键词、位置和其他重要信息。lucene-core-4.9.0.jar提供了一些类来帮助创建和维护索引,在搜索时可以快速定位相关文档。 另外,lucene-core-4.9.0.jar还提供了丰富的查询语法和API,以便开发人员可以根据特定的需求构建和执行复杂的查询。这些查询可以包括布尔逻辑、过滤器、范围查询和模糊匹配等多种形式。通过使用Lucene的查询功能,用户可以快速找到符合其需求的相关文档。 总之,lucene-core-4.9.0.jar是Lucene项目的核心库,提供了全文搜索引擎的关键功能和类。它可以帮助开发人员构建强大的搜索应用程序,实现快速和准确的搜索功能。 ### 回答3: lucene-core-4.9.0.jar 是一个用于构建搜索引擎的Java库。Lucene是一个开源的全文搜索引擎工具包,它提供了用于索引和搜索文本的功能。 lucene-core-4.9.0.jar 是Lucene库的核心组件,用于实现基本的搜索和索引功能。它包含了索引文档和搜索相关内容所需的所有必要类和方法。这个.jar文件是由Lucene 4.9.0版本的源代码编译而成的。 使用 lucene-core-4.9.0.jar,我们可以很方便地在自己的应用程序中实现搜索功能。首先,我们需要构建一个索引,将要搜索的文本内容进行索引化。然后,我们可以使用 Lucene 提供的 API 进行搜索操作,通过关键字或特定的查询语句来搜索索引中的内容。Lucene 提供了丰富的查询语法和搜索算法,可以根据需求进行高级的搜索操作,如模糊搜索、排序、过滤等。 通过使用 lucene-core-4.9.0.jar,我们可以为我们的应用程序添加强大的搜索能力,无论是搜索文件、数据库、网站内容或是其他结构化的数据。Lucene 库已经在众多应用中得到了广泛的应用,包括网站搜索引擎、文档管理系统、电子邮件客户端等。 总之,lucene-core-4.9.0.jar 是一个功能强大且灵活的Java库,可以帮助开发人员快速构建搜索引擎和实现全文搜索功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值