文档章节

Apache Lucene 6.3.0 Demo

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

准备工作

  1. JRE

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

  1. 依赖包

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

© 著作权归作者所有

共有 人打赏支持
烛✟孩
粉丝 3
博文 43
码字总数 13182
作品 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
2K
5
Apache Lucene 6.3.0 发布,Java 搜索引擎

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

淡漠悠然
2016/11/09
2.5K
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...

淡漠悠然
2018/08/02
1K
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-JE中文分词

首先需要导入两个jar包(lucene-core-2.4.1.jar,je-analysis-1.5.1.jar,lucene-highlighter-2.4.1.jar),注意版本的兼容问题,这里提供一个共享网盘的链接: 链接:http://pan.baidu.com/...

帅的不像男的
2016/05/24
58
0

没有更多内容

加载失败,请刷新页面

加载更多

CSS 选择器参考手册

CSS 选择器参考手册 选择器 描述 [attribute] 用于选取带有指定属性的元素。 [attribute=value] 用于选取带有指定属性和值的元素。 [attribute~=value] 用于选取属性值中包含指定词汇的元素。...

Jack088
今天
1
0
数据库篇一

数据库篇 第1章 数据库介绍 1.1 数据库概述  什么是数据库(DB:DataBase) 数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据...

stars永恒
今天
2
0
Intellij IDEA中设置了jsp页面,但是在访问页面时却提示404

在Intellij IDEA中设置了spring boot的jsp页面,但是在访问时,却出现404,Not Found,经过查找资料后解决,步骤如下: 在Run/Debug Configurations面板中设置该程序的Working Directory选项...

uknow8692
昨天
3
0
day24:文档第五行增内容|每月1号压缩/etc/目录|过滤文本重复次数多的10个单词|人员分组|

1、在文本文档1.txt里第五行下面增加如下内容;两个方法; # This is a test file.# Test insert line into this file. 分析:给文档后增加内容,可以用sed 来搞定;也可以用while do done...

芬野de博客
昨天
3
0
深入理解JVM—JVM内存模型

深入理解JVM—JVM内存模型 我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来越快,磁盘远远跟不上CPU的读写速度,才设计了内存...

onedotdot
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部