创建索引库的步骤:
- 1)创建JavaBean对象
- 2)创建Docment对象
- 3)将JavaBean对象所有的属性值,均放到Document对象中去,属性名可以和JavaBean相同或不同
- 4)创建IndexWriter对象
- 5)将Document对象通过IndexWriter对象写入索引库中
- 6)关闭IndexWriter对象
@Test public void createIndexDB() throws Exception { //把数据填充到JavaBean对象中 User user = new User("1", "钟福成", "未来的程序员"); //创建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(); }
这里写图片描述
程序执行完,我们就会在硬盘中见到我们的索引库。
这里写图片描述
那我们现在是不知道记录是否真真正正存储到索引库中的,因为我们看不见。索引库存放的数据放在cfs文件下,我们也是不能打开cfs文件的。
于是,我们现在用一个关键字,把索引库的数据读取。看看读取数据是否成功。
根据关键字查询索引库中的内容:
- 1)创建IndexSearcher对象
- 2)创建QueryParser对象
- 3)创建Query对象来封装关键字
- 4)用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
- 5)获取符合条件的编号
- 6)用indexSearcher对象去索引库中查询编号对应的Document对象
- 7)将Document对象中的所有属性取出,再封装回JavaBean对象中去,并加入到集合中保存,以备将之用
@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, "userName", 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); }
这里写图片描述
效果:
这里写图片描述
1.3进一步说明Lucene代码
我们的Lucene程序就是大概这么一个思路:将JavaBean对象封装到Document对象中,然后通过IndexWriter把document写入到索引库中。当用户需要查询的时候,就使用IndexSearcher从索引库中读取数据,找到对应的Document对象,从而解析里边的内容,再封装到JavaBean对象中让我们使用。
这里写图片描述
二、对Lucene代码优化
我们再次看回我们上一篇快速入门写过的代码,我来截取一些有代表性的:
以下代码在把数据填充到索引库,和从索引库查询数据的时候,都出现了。是重复代码!
Directory directory = FSDirectory.open(new File("E:/createIndexDB")); //使用标准的分词算法对原始记录表进行拆分 Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
以下的代码其实就是将JavaBean的数据封装到Document对象中,我们是可以通过反射来对其进行封装….如果不封装的话,我们如果有很多JavaBean都要添加到Document对象中,就会出现很多类似的代码。
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));
以下代码就是从Document对象中把数据取出来,封装到JavaBean去。如果JavaBean中有很多属性,也是需要我们写很多次类似代码….
//将Document对象中的所有属性取出,再封装回JavaBean对象中去 String id = document.get("id"); String userName = document.get("userName"); String sal = document.get("sal"); User user = new User(id, userName, sal);