lucene入门使用

版权声明:原创文章转载请声明出处https://blog.csdn.net/qq_40374604 https://blog.csdn.net/qq_40374604/article/details/85224780

简介:https://baike.baidu.com/item/Lucene/6753302?fr=aladdin

扩展停用词和新词:https://blog.csdn.net/u010357298/article/details/80776902

目录结构:(跟着代码练习一遍,效果更好)       摘要,排序和高亮           lucene4以后有一定改变

直接上代码 代码:

一:建立javabean

/**建立javabean*/
package lucene;

import com.alibaba.fastjson.JSON;

public class User {
	private String id;
	private String userName;
	private String sal;

	public User() {

	}

	public User(String id, String userName, String sal) {
		this.id = id;
		this.userName = userName;
		this.sal = sal;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getSal() {
		return sal;
	}

	public void setSal(String sal) {
		this.sal = sal;
	}

	// @Override
	// public String toString() {
	// return "User[id='" + id + "',userName='" + userName + "',sal='" + sal
	// + "']";
	// }

	/** 序列化 */
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return JSON.toJSONString(this);
	}
}

二:创建索引库并插入数据 

/**创建索引库并插入数据 */
package lucene;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

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.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class AddIndex {

	public void createIndexDB(String id, String userName, String sal)
			throws Exception {

		// 把数据填充到JavaBean对象中
		User user = new User(id, userName, sal);

		// 创建Document对象【导入的是Lucene包下的Document对象】
		Document document = new Document();

		// 将JavaBean对象所有的属性值,均放到Document对象中去,属性名可以和JavaBean相同或不同

		/**
		 * 向Document对象加入一个字段 参数一:字段的关键字 参数二:字符的值 参数三:是否要存储到原始记录表中 YES表示是 NO表示否
		 * 参数四:是否需要将存储的数据拆分到词汇表中 ANALYZED表示拆分 NOT_ANALYZED表示不拆分
		 *
		 * */
		document.add(new Field("id", user.getId(), Field.Store.YES,
				Field.Index.ANALYZED));
		document.add(new Field("userName", user.getUserName(), Field.Store.YES,
				Field.Index.ANALYZED));
		document.add(new Field("sal", user.getSal(), Field.Store.YES,
				Field.Index.ANALYZED));

		// 创建IndexWriter对象
		// 目录指定为E:/createIndexDB
		Directory directory = FSDirectory.open(new File("E:/createIndexDB"));

		// 使用标准的分词算法对原始记录表进行拆分
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);

		// LIMITED默认是1W个
		IndexWriter.MaxFieldLength maxFieldLength = IndexWriter.MaxFieldLength.LIMITED;
		/**
		 * IndexWriter将我们的document对象写到硬盘中
		 *
		 * 参数一:Directory d,写到硬盘中的目录路径是什么 参数二:Analyzer a,
		 * 以何种算法来对document中的原始记录表数据进行拆分成词汇表 参数三:MaxFieldLength mfl 最多将文本拆分出多少个词汇
		 *
		 * */
		IndexWriter indexWriter = new IndexWriter(directory, analyzer,
				maxFieldLength);

		// 将Document对象通过IndexWriter对象写入索引库中
		indexWriter.addDocument(document);

		// 关闭IndexWriter对象
		indexWriter.close();

	}

	public static void main(String[] args) {
		String id = "2";
		String userName = "李四";
		String sal = "运维工程师";
		AddIndex testIndex = new AddIndex();
		try {
			testIndex.createIndexDB(id, userName, sal);
			System.out.println("添加成功:" + id);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("createIndexDB error");
		}
		/** 读取文件内容,存入索引库 */
		try {
			String classPath = System.getProperties().getProperty("user.dir");
			String sep = System.getProperties().getProperty("file.separator");
			String pathName = classPath + sep + "date" + sep + "testtitle.txt";
			File file = new File(pathName);
			InputStreamReader reader = new InputStreamReader(
					new FileInputStream(file), "gbk");
			BufferedReader br = new BufferedReader(reader);
			String stringLine;
			int count = 0;
			while ((stringLine = br.readLine()) != null) {
				count += 1;
				testIndex.createIndexDB(count + "", stringLine.substring(0, 3),
						stringLine);
				System.out.println(stringLine);
			}
			br.close();
			reader.close();
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("createndexDB error");
		}

	}
}

三:查找

package lucene;

import java.io.File;
import java.net.URLDecoder;
import java.net.URLEncoder;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.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;
import org.apache.lucene.util.Version;
import org.junit.Test;

public class FindIndex {
	@Test
	public void findIndexDB() throws Exception {

		/**
		 * 参数一: IndexSearcher(Directory path)查询以xxx目录的索引库
		 *
		 * */
		Directory directory = FSDirectory.open(new File("E:/createIndexDB"));
		// 创建IndexSearcher对象
		IndexSearcher indexSearcher = new IndexSearcher(directory);

		// 创建QueryParser对象
		/**
		 * 参数一: Version matchVersion 版本号【和上面是一样的】 参数二:String f,【要查询的字段】
		 * 参数三:Analyzer a【使用的拆词算法】
		 * */
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
		QueryParser queryParser = new QueryParser(Version.LUCENE_30,
				"sal", analyzer);

		// 给出要查询的关键字
		String keyWords = "中国";

		// 创建Query对象来封装关键字
		Query query = queryParser.parse(keyWords);

		// 用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
		TopDocs topDocs = indexSearcher.search(query, 100);

		// 获取符合条件的编号

		for (int i = 0; i < topDocs.scoreDocs.length; i++) {

			ScoreDoc scoreDoc = topDocs.scoreDocs[i];
			int no = scoreDoc.doc;
			// 用indexSearcher对象去索引库中查询编号对应的Document对象
			Document document = indexSearcher.doc(no);

			// 将Document对象中的所有属性取出,再封装回JavaBean对象中去
			String id = document.get("id");
			String userName = document.get("userName");
			String sal = document.get("sal");

			User user = new User(id, userName, sal);
			System.out.println(user);

		}
		indexSearcher.close();
	}
}

四:删除

package lucene;

import java.io.File;
import java.io.IOException;
import java.io.Reader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

public class TestIndex {
	@Test
	/**删除索引库*/
	public void TestIndexDel() throws IOException {
		// TODO Auto-generated constructor stub
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
		FSDirectory directory = FSDirectory.open(new File("E:/createIndexDB"));
		// IndexWriterConfig
		IndexWriter.MaxFieldLength maxFieldLength = IndexWriter.MaxFieldLength.LIMITED;
		IndexWriter indexWriter = new IndexWriter(directory, analyzer,
				maxFieldLength);
		indexWriter.deleteAll();
		System.out.println("good--已删除索引库所有文件");
		indexWriter.deleteDocuments(new Term("userName", "李四"));
		indexWriter.commit();
		indexWriter.close();
	}
}

 五,优化

// 多条件搜索--(结果会排序)
		QueryParser queryParser1 = new MultiFieldQueryParser(
				LuceneUtils.getVersion(), new String[] { "userName", "sal" },
				LuceneUtils.getAnalyzer());

下面代码把lucene封装成工具包(转载)

package lucene;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created 0
 */

/**
 * 使用单例事例模式
 * */
public class LuceneUtils {
	private static Directory directory;
	private static Analyzer analyzer;
	private static IndexWriter.MaxFieldLength maxFieldLength;

	private LuceneUtils() {
	}

	static {
		try {
			directory = FSDirectory.open(new File("E:/createIndexDB"));
			analyzer = new StandardAnalyzer(Version.LUCENE_30);
			maxFieldLength = IndexWriter.MaxFieldLength.LIMITED;
		} catch (Exception e) {
			e.printStackTrace();

		}
	}

	public static Directory getDirectory() {
		return directory;
	}

	public static Analyzer getAnalyzer() {
		return analyzer;
	}

	public static IndexWriter.MaxFieldLength getMaxFieldLength() {
		return maxFieldLength;
	}

	/**
	 * @param object
	 *            传入的JavaBean类型
	 * @return 返回Document对象
	 */
	public static Document javaBean2Document(Object object) {
		try {
			Document document = new Document();
			// 得到JavaBean的字节码文件对象
			Class<?> aClass = object.getClass();

			// 通过字节码文件对象得到对应的属性【全部的属性,不能仅仅调用getFields()】
			Field[] fields = aClass.getDeclaredFields();

			// 得到每个属性的名字
			for (Field field : fields) {
				String name = field.getName();
				// 得到属性的值【也就是调用getter方法获取对应的值】
				String method = "get" + name.substring(0, 1).toUpperCase()
						+ name.substring(1);
				// 得到对应的值【就是得到具体的方法,然后调用就行了。因为是get方法,没有参数】
				Method aClassMethod = aClass.getDeclaredMethod(method, null);
				String value = aClassMethod.invoke(object).toString();
				System.out.println(value);

				// 把数据封装到Document对象中。
				document.add(new org.apache.lucene.document.Field(name, value,
						org.apache.lucene.document.Field.Store.YES,
						org.apache.lucene.document.Field.Index.ANALYZED));
			}
			return document;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @param aClass
	 *            要解析的对象类型,要用户传入进来
	 * @param document
	 *            将Document对象传入进来
	 * @return 返回一个JavaBean
	 */
	public static Object Document2JavaBean(Document document, Class<?> aClass) {
		try {
			// 创建该JavaBean对象
			Object obj = aClass.newInstance();
			// 得到该JavaBean所有的成员变量
			Field[] fields = aClass.getDeclaredFields();
			for (Field field : fields) {

				// 设置允许暴力访问
				field.setAccessible(true);
				String name = field.getName();
				String value = document.get(name);
				// 使用BeanUtils把数据封装到Bean中
				BeanUtils.setProperty(obj, name, value);
			}
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Test
	public void test() {
		User user = new User();
		LuceneUtils.javaBean2Document(user);
	}

}

猜你喜欢

转载自blog.csdn.net/qq_40374604/article/details/85224780
今日推荐