文档章节

Apache Lucene 6.3.0 Demo

烛✟孩
 烛✟孩
发布于 2017/02/12 11:09
字数 1362
阅读 44
收藏 0

###准备工作

1 JRE

本着凡事都用新版本的原则,本人的的jdk是1.8版本,完美运行。 但为了验证Apache Lucene 6.3.0需要jdk1.8的传说, 于是乎换了jdk1.7,发现果然运行不了, 收到来自虚拟机的报错。

2 依赖包

pom.xml的dependencies中加入如下代码后,自动导入了

  • lucene-queryparser-6.3.0.jar

  • lucene-core-6.3.0.jar

  • lucene-queries-6.3.0.jar

  • lucene-sandbox-6.3.0.jar

      <dependency>
      	<groupId>org.apache.lucene</groupId>
      	<artifactId>lucene-queryparser</artifactId>
      	<version>6.3.0</version>
      </dependency>
    

###开始码字

package com.lucene.test;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class FSDirectoryDemo {
    private static String INDEX_DIR = "D://LuceneTest//index";// 索引存放目录  
    
    private Directory directory;  
    private Analyzer analyzer;

    public FSDirectoryDemo() throws Exception {
		super();
		analyzer = new StandardAnalyzer();
		directory = initLuceneDirctory();
	}

	/***
	 * 初始化索引文件目录
	 * 
	 * [@return](https://my.oschina.net/u/556800)
	 * [@throws](https://my.oschina.net/throws) Exception
	 */
	private Directory initLuceneDirctory() throws Exception {
		if (directory == null) {
			File indexDir = new File(INDEX_DIR);
			/*
			 * 文件目录
			 * 把索引文件存储到磁盘目录
			 * 索引文件可放的位置:索引可以存放在两个地方
			 * 1.硬盘,directory = FSDirectory.open(Path path);
			 * 2.内存;directory = new RAMDirectory();
			 * 放在硬盘上可以用FSDirectory(),放在内存的用RAMDirectory()不过一关机就没了
			 */
			directory = FSDirectory.open(indexDir.toPath());
		}
		return directory;
	};

	/**
	 * 该方法用来创建org.apache.lucene.document.Document对象。
	 * 从代码上看,Document对象封装着被检索的文档,里面包含着多个Field对象。
	 * 本段代码用的构造方法为Field(String name, String value, FieldType type),
	 * 参数分别为Field的name,value和type。
	 * TextField对象里有两个常量,TYPE_NOT_STORED和TYPE_STORED,
	 * 表示该Field检索到之后是否被储存,这一点后面会演示。
	 * [@param](https://my.oschina.net/u/2303379) title
	 * [@param](https://my.oschina.net/u/2303379) content
	 * [@return](https://my.oschina.net/u/556800)
	 */
	public static Document createDocument(String title, String content) {
		Document doc = new Document();
		doc.add(new Field("content", content, TextField.TYPE_STORED));
		doc.add(new Field("title", title, TextField.TYPE_STORED));
		doc.add(new Field("author", "paul", TextField.TYPE_NOT_STORED));
		return doc;
	}

	/**
	 * 添加索引,此处是写死的,实际开发中,可以从数据库中读取
	 * @throws IOException
	 */
	public void addDirectory() throws IOException {
		IndexWriterConfig iwc = new IndexWriterConfig();
		IndexWriter writer = new IndexWriter(directory, iwc);
		
		/*
		 * 这里给IndexWriter writer对象添加了3个Document对象
		 * 后面调用IndexSearcher的方法时,并未用到此处的IndexWriter writer,
		 * 但看上去,我们把被检索的内容都放到了该对象里,这是为什么呢?
		 * 答案就是通过前面和后面各种对象之间的关联实现的
		 */
		writer.addDocument(createDocument("FieldName_1", "FieldValue content one"));
		writer.addDocument(createDocument("FieldName title two test", "FieldValue two"));
		writer.addDocument(createDocument("FieldName title three test", "FieldValue three"));
		writer.addDocument(createDocument("FieldName test title fore test", "FieldValue fore"));
		
		writer.commit();
		writer.close();
	}
	
	public void luceneDemo() throws Exception {
		IndexReader ir = DirectoryReader.open(directory);
		IndexSearcher searcher = new IndexSearcher(ir);
		/*
		 * 此处有个"title",下行代码也有一个"title",
		 * 查看QueryParser源代码发现,
		 * QueryParser(String f, Analyzer a)
		 * 对这个构造方法的第一个参数注释
		 * the default field for query terms.
		 */
		QueryParser qp = new QueryParser("title", analyzer);
		
		/*
		 * 查看Query parse(String query)源代码发现,
		 * 参数此处格式为"name:'value'"时,从当前指定name中检索
		 * 如果只是一个普通String类型对象时,则从QueryParser中第一个参数String f指定的name中检索
		 */
		Query query = qp.parse("title:'fieldName test'");
		
		/*
		 * 此处是执行检索的语句。
		 * TopDocs search(Query, int)
		 * 通过前面的准备工作,Query封装了查询所需要的各种前提,
		 * 包括内容和规则
		 * int,通过查源码得知,是返回的最大结果数。
		 * 
		 * TopDocs封装了查询返回的结果,
		 * 其中totalHits是命中的个数
		 * 
		 * 此处有疑问请接着往下看
		 */
		TopDocs topdoc = searcher.search(query, 2);
		System.out.println("命中个数:" + topdoc.totalHits);
		

		/*
		 * scoreDocs封装了返回的文档的检索得分排序,里面三个属性
		 * 
		 * The score of this document for the query
		 * float score 文档相关程度的得分
		 * 
		 * A hit document's number. @see IndexSearcher#doc(int)
		 * int doc 文档的index序号
		 * 
		 * Only set by {@link TopDocs#merge}
		 * int shardIndex	查源码得知,是在TopDocs[]合并的时候用到的index
		 * 此处我们只有一个TopDocs对象,所以就用不上了
		 * 
		 */
		ScoreDoc[] hits = topdoc.scoreDocs;
		System.out.println("hits: "+Arrays.toString(hits));

		/*
		 * 从输出结果可以看出,
		 * FieldName test title fore test文档关联程度得分score较高,
		 * 所以排在前面
		 * 
		 * ****** 此处可以看出search(Query, int)中的int、totalHits与hits.length的区别 *****
		 * int是最大结果数,search源码里调用IndexSearcher类中TopDocs searchAfter(ScoreDoc, Query, int)可以看到,
		 * final int limit = Math.max(1, reader.maxDoc());
		 * numHits = Math.min(numHits, limit);
		 * 此处numHits为传入的int,
		 * 最终检索结果取的是int和和命中数目小的那个值
		 * 此次检索命中3个,但传入的int为2,
		 * 所以最终显示了两条结果
		 */
		if (hits != null && hits.length > 0) {
			for (int i = 0; i < hits.length; i++) {
				Document hitDoc = searcher.doc(hits[i].doc);
				//由于content的FieldType为TYPE_STORED,所以可以输出
				System.out.println(hitDoc.get("content"));
				//由于author的FieldType为TYPE_NOT_STORED,所以输出为null
				System.out.println(hitDoc.get("author"));
			}
		}
	}

	public static void main(String[] args) {
		try {
			FSDirectoryDemo fsdd = new FSDirectoryDemo();
			/*
			 * 第一次执行时,要创建索引,
			 * 之后再执行时,下面行就可以注释掉了
			 */
//			fsdd.addDirectory();
			fsdd.luceneDemo();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

输出结果

命中个数:3
hits: [doc=3 score=0.7275808 shardIndex=0, doc=1 score=0.6739625 shardIndex=0]
FieldValue fore
null
FieldValue two
null

如果用jdk1.7,报错如下

Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/lucene/analysis/Analyzer : Unsupported major.minor version 52.0
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2531)
	at java.lang.Class.getMethod0(Class.java:2774)
	at java.lang.Class.getMethod(Class.java:1663)
	at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)

参考文档:http://blog.csdn.net/lb521200200/article/details/53549660

© 著作权归作者所有

共有 人打赏支持
烛✟孩
粉丝 2
博文 28
码字总数 6343
作品 0
程序员
Apache Solr 6.3.0 发布,Java 全文搜索服务器

Apache Solr 6.3.0 发布了。 Apache Solr (读音: SOLer) 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。 更新内容: Optimize, store and deploy...

淡漠悠然
2016/11/09
1K
5
Apache Lucene 6.3.0 发布,Java 搜索引擎

Apache Lucene 6.3.0 发布了。 Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene的目的...

淡漠悠然
2016/11/09
2.3K
2
Jest 6.3.0 发布,ElasticSearch 的 Java HTTP Rest 客户端

Jest 6.3.0 发布了,Jest 是 ElasticSearch 的 Java HTTP Rest 客户端。 更新如下: 兼容 ES6 依赖版本升级: Elasticsearch 5.3.2 6.3.1 Lucene 6.4.2 7.3.1 改进:默认脚本语言设置为 PAIN...

淡漠悠然
08/02
0
0
centos6.7部署solr-6.3.0

因为solr-6.3.0比较新,在centos中部署的教程也比较少,所以我自己就部署了一次,有什么不对的地方请大家多多指教 环境如下 系统:centos6.7 JDK:1.8.0_111 Tomcat:apache-tomcat-8.5.6 s...

lujiawei
2016/12/10
274
0
为什么总是出现这个代码

我在控制台下测试lucene的demo时候,总是出现这样的错误 配置的路径为 ;d:lucene-3.0.0lucene-demos-3.0.0.jar;d:lucene-3.0.0lib;d:lucene-3.0.0lucene-core-3.0.0.jar 输入java org.apache......

鹏飞
2010/06/19
261
0

没有更多内容

加载失败,请刷新页面

加载更多

开发命令行工具的 12 个最佳实践

简评:设计良好的命令行应用是极富生产力的工具,本文介绍了开发命令行工具的 12 个最佳实践 CLI 是构建产品的绝佳方式,与 Web 应用不同的是它需要的时间更少,并且功能更强大。使用Web,你...

极光推送
27分钟前
2
0
DRAM和NAND Flash合约价持续走下坡路

大伙儿关心的内存和SSD产品价格在年内有望继续迎来一波减价。 据TrendForce旗下的DRAMeXchange发布的最新报告显示,本应该是购物旺季的Q4,DRAM芯片和NAND Flash芯片的合约采购价均呈现疲软的...

linux-tao
31分钟前
1
0
Vue学习记录

Vue学习记录 Vue实例 Vue实例的创建 var vm = new Vue({ // 选项}) 数据冻结 使用 Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。 var obj = { foo: 'ba...

BakerZhu
31分钟前
1
0
day124-20181022-英语流利阅读-待学习

靠打零工能走上人生巅峰吗? Daniel 2018-10-22 1.今日导读 “零工经济”,一般指通过网站或 App 获得一些零碎的工作机会,从事不稳定的工作,赚取不稳定的薪水。由于从事这样的工作门槛相比...

飞鱼说编程
36分钟前
2
0
python学习笔记

马克

孙幼凌
45分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部