本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
在使用 Lucene 的过程中,我们需要通过 FSDirectory.open(Paths.get("D:\\xttblog")); 之类的得到 lucene 的索引目录。然后再得到 IndexWriter,或者通过 DirectoryReader.open() 直接得到 IndexReader,然后我们再通过 IndexSearcher 进行索引搜索。但是现在有一个新的问题,我的索引目录存在多个,那么改如何何必多个 IndexReader 实现多索引的合并搜索呢?答案就是本文的 MultiReader!
MultiReader 的构造函数是一个可变参数列表。通过 MultiReader(IndexReader… subReaders)可以接收多个 IndexReader 实例,然后再合并成一个 IndexSearcher,这样就可以做到多索引文件的合并搜索。
import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.core.WhitespaceAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.StringField; import org.apache.lucene.index.*; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermRangeQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.util.BytesRef; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.IOException; /** * Description:测试有多个索引文件的情况下,如何进行搜索并合并搜索结果 */ public class MultiReaderDemo { private Analyzer analyzer = new WhitespaceAnalyzer(); Directory aDirectory = new RAMDirectory(); Directory bDirectory = new RAMDirectory(); IndexWriterConfig aIndexWriterConfig = new IndexWriterConfig(analyzer); IndexWriterConfig bIndexWriterConfig = new IndexWriterConfig(analyzer); IndexWriter aIndexWriter; IndexWriter bIndexWriter; @Before public void setUp() throws IOException { String[] animals = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}; aIndexWriter = new IndexWriter(aDirectory, aIndexWriterConfig); bIndexWriter = new IndexWriter(bDirectory, bIndexWriterConfig); for (int i = 0; i < animals.length; i++) { Document document = new Document(); String animal = animals[i]; document.add(new StringField("animal", animal, Field.Store.YES)); if (animal.charAt(0) < 'n') { aIndexWriter.addDocument(document); } else { bIndexWriter.addDocument(document); } } aIndexWriter.commit(); bIndexWriter.commit(); } @After public void setDown() { try { if (aIndexWriter != null && aIndexWriter.isOpen()) { aIndexWriter.close(); } if (bIndexWriter != null && bIndexWriter.isOpen()) { bIndexWriter.close(); } } catch (IOException e) { e.printStackTrace(); } } @Test public void testMultiReader() throws IOException { IndexReader aIndexReader = DirectoryReader.open(aDirectory); IndexReader bIndexReader = DirectoryReader.open(bDirectory); MultiReader multiReader = new MultiReader(aIndexReader, bIndexReader); IndexSearcher indexSearcher = new IndexSearcher(multiReader); TopDocs animal = indexSearcher.search(new TermRangeQuery("animal", new BytesRef("h"), new BytesRef("q"), true, true), 10); Assert.assertEquals(10, animal.totalHits); ScoreDoc[] scoreDocs = animal.scoreDocs; for (ScoreDoc sd : scoreDocs) { System.out.println(indexSearcher.doc(sd.doc)); } } }
一个 IndexReader 实例对应一个索引文件目录,通过 MultiReader 接收多个 IndexReader 实例,之后用该 MultiReader 实例初始化 IndexSearcher。
需要注意的是,IndexReader 实例是完全线程安全的,多线程可以调用其任何方法,因而无需对 IndexReader 实例进行同步。如果你的应用需要外部同步操作,对你自己的对象进行同步,而不是 Lucene。
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!