- 浏览: 1054035 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1441)
- 软件思想&演讲 (9)
- 行业常识 (250)
- 时时疑问 (5)
- java/guava/python/php/ruby/R/scala/groovy (213)
- struct/spring/springmvc (37)
- mybatis/hibernate/JPA (10)
- mysql/oracle/sqlserver/db2/mongdb/redis/neo4j/GreenPlum/Teradata/hsqldb/Derby/sakila (268)
- js/jquery/jqueryUi/jqueryEaseyUI/extjs/angulrJs/react/es6/grunt/zepto/raphael (81)
- ZMQ/RabbitMQ/ActiveMQ/JMS/kafka (17)
- lucene/solr/nuth/elasticsearch/MG4J (167)
- html/css/ionic/nodejs/bootstrap (19)
- Linux/shell/centos (56)
- cvs/svn/git/sourceTree/gradle/ant/maven/mantis/docker/Kubernetes (26)
- sonatype nexus (1)
- tomcat/jetty/netty/jboss (9)
- 工具 (17)
- ETL/SPASS/MATLAB/RapidMiner/weka/kettle/DataX/Kylin (11)
- hadoop/spark/Hbase/Hive/pig/Zookeeper/HAWQ/cloudera/Impala/Oozie (190)
- ios/swift/android (9)
- 机器学习&算法&大数据 (18)
- Mesos是Apache下的开源分布式资源管理框架 (1)
- echarts/d3/highCharts/tableau (1)
- 行业技能图谱 (1)
- 大数据可视化 (2)
- tornado/ansible/twisted (2)
- Nagios/Cacti/Zabbix (0)
- eclipse/intellijIDEA/webstorm (5)
- cvs/svn/git/sourceTree/gradle/jira/bitbucket (4)
- jsp/jsf/flex/ZKoss (0)
- 测试技术 (2)
- splunk/flunm (2)
- 高并发/大数据量 (1)
- freemarker/vector/thymeleaf (1)
- docker/Kubernetes (2)
- dubbo/ESB/dubboX/wso2 (2)
最新评论
介绍了IndexWriter的作用,它的最大价值体现在对索引的创建,管理和维护上,通过与IndexWriterConfig这个配置管理类的组合,可以实现最佳的索引策略,当然前提是你得了解IndexWriterConfig里一些重要的参数的配置含义。
本篇文章散仙要介绍的是IndexSearcher这个类,这个类是Lucene在进行检索时必不可少的一个组件,可以称为是检索的入口,通过这个入口之后,我们就可以获取与我们检索的关键词相关的一系列Doc,然后我们就可以进行后续相关的业务处理。
所以我们经常会在代码里这样写:
Java代码 复制代码 收藏代码
1.Directory directory=FSDirectory.open(new File("D:\\索引测试"));//获取一个索引目录
2.IndexReader reader=DirectoryReader.open(directory);//返回一个复合Reader=》DirectoryReader
3. //构造IndexSearcher 检索环境
4.IndexSearcher searcher=new IndexSearcher(reader);
大多数,情况下,我们的代码都是这样写的,实际上IndexSearcher的构造函数有4个,我们最常用的一般有2个,部分源码如下:
Java代码 复制代码 收藏代码
1.final IndexReader reader; // package private for testing!
2.
3. // NOTE: these members might change in incompatible ways
4. // in the next release
5. protected final IndexReaderContext readerContext;
6. protected final List<AtomicReaderContext> leafContexts;
7. /** used with executor - each slice holds a set of leafs executed within one thread */
8. protected final LeafSlice[] leafSlices;
9.
10. // These are only used for multi-threaded search
11. private final ExecutorService executor;
12.
13. // the default Similarity
14. private static final Similarity defaultSimilarity = new DefaultSimilarity();
15.
16. /**
17. * Expert: returns a default Similarity instance.
18. * In general, this method is only called to initialize searchers and writers.
19. * User code and query implementations should respect
20. * {@link IndexSearcher#getSimilarity()}.
21. * @lucene.internal
22. */
23. public static Similarity getDefaultSimilarity() {
24. return defaultSimilarity;
25. }
26.
27. /** The Similarity implementation used by this searcher. */
28. private Similarity similarity = defaultSimilarity;
29.
30. /** Creates a searcher searching the provided index. */
31. public IndexSearcher(IndexReader r) {
32. //调用的是2参的构造函数
33. this(r,null);
34. }
35.
36. /** Runs searches for each segment separately, using the
37. * provided ExecutorService. IndexSearcher will not
38. * shutdown/awaitTermination this ExecutorService on
39. * close; you must do so, eventually, on your own. NOTE:
40. * if you are using {@link NIOFSDirectory}, do not use
41. * the shutdownNow method of ExecutorService as this uses
42. * Thread.interrupt under-the-hood which can silently
43. * close file descriptors (see <a
44. * href="https://issues.apache.org/jira/browse/LUCENE-2239">LUCENE-2239</a>).
45. *
46. * @lucene.experimental */
47. public IndexSearcher(IndexReader r, ExecutorService executor) {
48.
49. this(r.getContext(), executor);
50. }
看了源码,我们就会发现,我们常用的构造函数实际上是会调用含有线程池并行检索的2参的构造方法,只不过,把线程池设置为null而已,这其实是一个优化的操作,在某些时候能够带来极大的性能提升,这个稍后散仙会详细分析。下面先来看下IndexSearcher里面的一些常用的API方法
方法名 描述
IndexSearcher(IndexReader r) 构建一个搜索实例,使用指定的Reader
IndexSearcher(IndexReader r, ExecutorService executor) 创建一个并行的检索实例,使用ExecutorService 提供的线程池
doc(int docID) 通过一个docid获取一个对应的doc
explain(Query query, int doc) 获取query详细的评分依据信息
getIndexReader() 获取IndexReader实例
search(Query query, int n) 获取前N个检索的结果
search(Query query, Collector results) 通过collector对检索结果进行自定义控制
search(Query query, Filter filter, Collector results) 通过检索,过滤,以及收集,获取一个特定的检索结果
search(Query query, Filter filter, int n) 经过滤后 的前N个结果
search(Query query, Filter filter, int n, Sort sort) 经过滤,排序后的前n个结果
search(Query query, Filter filter, int n, Sort sort, boolean doDocScores, boolean doMaxScore) 对排序后的结果,是否开启评分策略
searchAfter(ScoreDoc after, Query query, int n) 检索上一次query后的数据,通常用来分页使用
setSimilarity(Similarity similarity) 设置自定义的打分策略
search(Weight weight, int nDocs, Sort sort, boolean doDocScores, boolean doMaxScore) 检索指定分数以上的结果
IndexSearcher类里面提供了大量的方法,用来对检索的数据集的限制和过滤,从而达到我们业务需要的一部分数据,当然我们也可也通过setSimilarity方法来设置我们的自定义的打分策略,还可以通过其他的一些方法,来实现排序,过滤,收集,调试打分信息等等。
最后,回到文章开始,散仙来分析下,IndexSearcher的并行构造,如何使用多线程来提升检索性能。
大多数时候,我们默认使用的都是单线程检索,这时候的检索总耗时是顺序检索所有段文件的时间之和,而如果我们使用了并行检索,这时候,我们的检索总耗时,其实就是检索段文件里,耗时最大的那个线程的时间,因为我们是并行检索,所以影响耗时的其实就是检索耗时最长的那个线程的耗时,这有点像“木桶效应”,决定木桶装水的多少,不是由最长的木板决定的,而是由最短的那块木板决定的,反映到这里,其实就是散仙刚提及的耗时可能最长的那个线程,决定了检索的总耗时。
首先呢,这个功能,并不是说所有的场景下,都有明显的作用,比如,我的索引里就只有一个段文件,那么你开启再多的线程也没用,因为这个并行检索,是一个线程对应一个段文件。
另外一种情况,我的索引非常小,然后我又压缩成多个段文件,然后使用这个并行检索去检索数据,其实这时候的性能可能连一个单线程都不如,这也就是单线程与多线程的使用场景的区分,只要正确的理解了什么时候使用单线程,什么时候使用多线程,才有可能达到我们最想要的结果。
所以,这个并行优化的功能,最适合的场景就是我的索引非常大,然后我们把这份索引,压缩成了多个段文件,可能有5个,或者10个以上的段文件,这时候利用这个功能,检索就有很大优势了,下面我们在来看下源码里具体处理:
Java代码 复制代码 收藏代码
1.if (executor == null) {
2. return search(leafContexts, weight, after, nDocs);
3. } else {
4. //通过一个公用的队列,来合并结果集
5. final HitQueue hq = new HitQueue(nDocs, false);
6. final Lock lock = new ReentrantLock();//锁
7. final ExecutionHelper<TopDocs> runner = new ExecutionHelper<TopDocs>(executor);
8.
9. for (int i = 0; i < leafSlices.length; i++) { // search each sub
10. runner.submit(new SearcherCallableNoSort(lock, this, leafSlices[i], weight, after, nDocs, hq));
11. }
12.
13. int totalHits = 0;
14. float maxScore = Float.NEGATIVE_INFINITY;
15. for (final TopDocs topDocs : runner) {
16. if(topDocs.totalHits != 0) {
17. totalHits += topDocs.totalHits;
18. maxScore = Math.max(maxScore, topDocs.getMaxScore());
19. }
20. }
21.
22. //最后从队列里,取值给ScoreDoc进行返回
23. final ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
24. for (int i = hq.size() - 1; i >= 0; i--) // put docs in array
25. scoreDocs[i] = hq.pop();
然后在具体的线程类里的实现:
Java代码 复制代码 收藏代码
1.private static final class SearcherCallableNoSort implements Callable<TopDocs> {
2.
3. private final Lock lock;
4. private final IndexSearcher searcher;
5. private final Weight weight;
6. private final ScoreDoc after;
7. private final int nDocs;
8. private final HitQueue hq;
9. private final LeafSlice slice;
10.
11. public SearcherCallableNoSort(Lock lock, IndexSearcher searcher, LeafSlice slice, Weight weight,
12. ScoreDoc after, int nDocs, HitQueue hq) {
13. this.lock = lock;
14. this.searcher = searcher;
15. this.weight = weight;
16. this.after = after;
17. this.nDocs = nDocs;
18. this.hq = hq;
19. this.slice = slice;
20. }
21.
22. @Override
23. public TopDocs call() throws IOException {
24. final TopDocs docs = searcher.search(Arrays.asList(slice.leaves), weight, after, nDocs);
25. final ScoreDoc[] scoreDocs = docs.scoreDocs;
26. //it would be so nice if we had a thread-safe insert
27. lock.lock();
28. try {
29. for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq
30. final ScoreDoc scoreDoc = scoreDocs[j];
31. if (scoreDoc == hq.insertWithOverflow(scoreDoc)) {
32. break;
33. }
34. }
35. } finally {
36. lock.unlock();
37. }
38. return docs;
39. }
40.}
通过源码,我们大概可以看出,这个提升,其实是利用了多线程的方式来完成的,通过实现Callable接口,以及重写其的call方法,最后通过公用的全局锁,来控制把检索到的结果集添加到公用的命中队列里,这样一来,一个检索,就被并行的分散到多个线程里,然后最后通过一个全局的容器,来获取所有线程检索的结果,由此以来,在某些场合就能大大提升检索性能。
当然这种提升是否,还跟我们的硬件环境有关系,如果我们的机器CPU不够强劲,或者我们在单核或双核上的机器上跑,可能会出现预期之外的结果,不过,现在的服务器基本都是配置很好的,一般不会出现这种情况。
本篇文章散仙要介绍的是IndexSearcher这个类,这个类是Lucene在进行检索时必不可少的一个组件,可以称为是检索的入口,通过这个入口之后,我们就可以获取与我们检索的关键词相关的一系列Doc,然后我们就可以进行后续相关的业务处理。
所以我们经常会在代码里这样写:
Java代码 复制代码 收藏代码
1.Directory directory=FSDirectory.open(new File("D:\\索引测试"));//获取一个索引目录
2.IndexReader reader=DirectoryReader.open(directory);//返回一个复合Reader=》DirectoryReader
3. //构造IndexSearcher 检索环境
4.IndexSearcher searcher=new IndexSearcher(reader);
大多数,情况下,我们的代码都是这样写的,实际上IndexSearcher的构造函数有4个,我们最常用的一般有2个,部分源码如下:
Java代码 复制代码 收藏代码
1.final IndexReader reader; // package private for testing!
2.
3. // NOTE: these members might change in incompatible ways
4. // in the next release
5. protected final IndexReaderContext readerContext;
6. protected final List<AtomicReaderContext> leafContexts;
7. /** used with executor - each slice holds a set of leafs executed within one thread */
8. protected final LeafSlice[] leafSlices;
9.
10. // These are only used for multi-threaded search
11. private final ExecutorService executor;
12.
13. // the default Similarity
14. private static final Similarity defaultSimilarity = new DefaultSimilarity();
15.
16. /**
17. * Expert: returns a default Similarity instance.
18. * In general, this method is only called to initialize searchers and writers.
19. * User code and query implementations should respect
20. * {@link IndexSearcher#getSimilarity()}.
21. * @lucene.internal
22. */
23. public static Similarity getDefaultSimilarity() {
24. return defaultSimilarity;
25. }
26.
27. /** The Similarity implementation used by this searcher. */
28. private Similarity similarity = defaultSimilarity;
29.
30. /** Creates a searcher searching the provided index. */
31. public IndexSearcher(IndexReader r) {
32. //调用的是2参的构造函数
33. this(r,null);
34. }
35.
36. /** Runs searches for each segment separately, using the
37. * provided ExecutorService. IndexSearcher will not
38. * shutdown/awaitTermination this ExecutorService on
39. * close; you must do so, eventually, on your own. NOTE:
40. * if you are using {@link NIOFSDirectory}, do not use
41. * the shutdownNow method of ExecutorService as this uses
42. * Thread.interrupt under-the-hood which can silently
43. * close file descriptors (see <a
44. * href="https://issues.apache.org/jira/browse/LUCENE-2239">LUCENE-2239</a>).
45. *
46. * @lucene.experimental */
47. public IndexSearcher(IndexReader r, ExecutorService executor) {
48.
49. this(r.getContext(), executor);
50. }
看了源码,我们就会发现,我们常用的构造函数实际上是会调用含有线程池并行检索的2参的构造方法,只不过,把线程池设置为null而已,这其实是一个优化的操作,在某些时候能够带来极大的性能提升,这个稍后散仙会详细分析。下面先来看下IndexSearcher里面的一些常用的API方法
方法名 描述
IndexSearcher(IndexReader r) 构建一个搜索实例,使用指定的Reader
IndexSearcher(IndexReader r, ExecutorService executor) 创建一个并行的检索实例,使用ExecutorService 提供的线程池
doc(int docID) 通过一个docid获取一个对应的doc
explain(Query query, int doc) 获取query详细的评分依据信息
getIndexReader() 获取IndexReader实例
search(Query query, int n) 获取前N个检索的结果
search(Query query, Collector results) 通过collector对检索结果进行自定义控制
search(Query query, Filter filter, Collector results) 通过检索,过滤,以及收集,获取一个特定的检索结果
search(Query query, Filter filter, int n) 经过滤后 的前N个结果
search(Query query, Filter filter, int n, Sort sort) 经过滤,排序后的前n个结果
search(Query query, Filter filter, int n, Sort sort, boolean doDocScores, boolean doMaxScore) 对排序后的结果,是否开启评分策略
searchAfter(ScoreDoc after, Query query, int n) 检索上一次query后的数据,通常用来分页使用
setSimilarity(Similarity similarity) 设置自定义的打分策略
search(Weight weight, int nDocs, Sort sort, boolean doDocScores, boolean doMaxScore) 检索指定分数以上的结果
IndexSearcher类里面提供了大量的方法,用来对检索的数据集的限制和过滤,从而达到我们业务需要的一部分数据,当然我们也可也通过setSimilarity方法来设置我们的自定义的打分策略,还可以通过其他的一些方法,来实现排序,过滤,收集,调试打分信息等等。
最后,回到文章开始,散仙来分析下,IndexSearcher的并行构造,如何使用多线程来提升检索性能。
大多数时候,我们默认使用的都是单线程检索,这时候的检索总耗时是顺序检索所有段文件的时间之和,而如果我们使用了并行检索,这时候,我们的检索总耗时,其实就是检索段文件里,耗时最大的那个线程的时间,因为我们是并行检索,所以影响耗时的其实就是检索耗时最长的那个线程的耗时,这有点像“木桶效应”,决定木桶装水的多少,不是由最长的木板决定的,而是由最短的那块木板决定的,反映到这里,其实就是散仙刚提及的耗时可能最长的那个线程,决定了检索的总耗时。
首先呢,这个功能,并不是说所有的场景下,都有明显的作用,比如,我的索引里就只有一个段文件,那么你开启再多的线程也没用,因为这个并行检索,是一个线程对应一个段文件。
另外一种情况,我的索引非常小,然后我又压缩成多个段文件,然后使用这个并行检索去检索数据,其实这时候的性能可能连一个单线程都不如,这也就是单线程与多线程的使用场景的区分,只要正确的理解了什么时候使用单线程,什么时候使用多线程,才有可能达到我们最想要的结果。
所以,这个并行优化的功能,最适合的场景就是我的索引非常大,然后我们把这份索引,压缩成了多个段文件,可能有5个,或者10个以上的段文件,这时候利用这个功能,检索就有很大优势了,下面我们在来看下源码里具体处理:
Java代码 复制代码 收藏代码
1.if (executor == null) {
2. return search(leafContexts, weight, after, nDocs);
3. } else {
4. //通过一个公用的队列,来合并结果集
5. final HitQueue hq = new HitQueue(nDocs, false);
6. final Lock lock = new ReentrantLock();//锁
7. final ExecutionHelper<TopDocs> runner = new ExecutionHelper<TopDocs>(executor);
8.
9. for (int i = 0; i < leafSlices.length; i++) { // search each sub
10. runner.submit(new SearcherCallableNoSort(lock, this, leafSlices[i], weight, after, nDocs, hq));
11. }
12.
13. int totalHits = 0;
14. float maxScore = Float.NEGATIVE_INFINITY;
15. for (final TopDocs topDocs : runner) {
16. if(topDocs.totalHits != 0) {
17. totalHits += topDocs.totalHits;
18. maxScore = Math.max(maxScore, topDocs.getMaxScore());
19. }
20. }
21.
22. //最后从队列里,取值给ScoreDoc进行返回
23. final ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
24. for (int i = hq.size() - 1; i >= 0; i--) // put docs in array
25. scoreDocs[i] = hq.pop();
然后在具体的线程类里的实现:
Java代码 复制代码 收藏代码
1.private static final class SearcherCallableNoSort implements Callable<TopDocs> {
2.
3. private final Lock lock;
4. private final IndexSearcher searcher;
5. private final Weight weight;
6. private final ScoreDoc after;
7. private final int nDocs;
8. private final HitQueue hq;
9. private final LeafSlice slice;
10.
11. public SearcherCallableNoSort(Lock lock, IndexSearcher searcher, LeafSlice slice, Weight weight,
12. ScoreDoc after, int nDocs, HitQueue hq) {
13. this.lock = lock;
14. this.searcher = searcher;
15. this.weight = weight;
16. this.after = after;
17. this.nDocs = nDocs;
18. this.hq = hq;
19. this.slice = slice;
20. }
21.
22. @Override
23. public TopDocs call() throws IOException {
24. final TopDocs docs = searcher.search(Arrays.asList(slice.leaves), weight, after, nDocs);
25. final ScoreDoc[] scoreDocs = docs.scoreDocs;
26. //it would be so nice if we had a thread-safe insert
27. lock.lock();
28. try {
29. for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq
30. final ScoreDoc scoreDoc = scoreDocs[j];
31. if (scoreDoc == hq.insertWithOverflow(scoreDoc)) {
32. break;
33. }
34. }
35. } finally {
36. lock.unlock();
37. }
38. return docs;
39. }
40.}
通过源码,我们大概可以看出,这个提升,其实是利用了多线程的方式来完成的,通过实现Callable接口,以及重写其的call方法,最后通过公用的全局锁,来控制把检索到的结果集添加到公用的命中队列里,这样一来,一个检索,就被并行的分散到多个线程里,然后最后通过一个全局的容器,来获取所有线程检索的结果,由此以来,在某些场合就能大大提升检索性能。
当然这种提升是否,还跟我们的硬件环境有关系,如果我们的机器CPU不够强劲,或者我们在单核或双核上的机器上跑,可能会出现预期之外的结果,不过,现在的服务器基本都是配置很好的,一般不会出现这种情况。
发表评论
-
elasticsearch异常信息汇总
2017-11-06 09:34 15471.IndexMissingException 异常信息 ... -
Elasticsearch的架构
2018-03-22 10:30 510为什么要学习架构? Elasticsearch的一些架构 ... -
怎么在Ubuntu上打开端口
2017-10-21 20:45 0Netstat -tln 命令是用来查看linux的端口使用情 ... -
Elasticsearch工作原理
2018-03-22 10:30 451一、关于搜索引擎 各 ... -
Elasticsearch的路由(Routing)特性
2017-10-11 10:41 0Elasticsearch路由机制介 ... -
Elasticsearch中的segment理解
2017-10-11 09:58 1891在Elasticsearch中, 需要搞清楚几个名词,如se ... -
Elasticsearch的路由(Routing)特性
2017-09-28 16:52 618Elasticsearch路由机制介绍 Elastics ... -
Elasticsearch 的 Shard 和 Segment
2017-09-28 16:05 1200Shard(分片) 一个Shard就是一个Lu ... -
开源大数据查询分析引擎现状
2017-09-22 03:04 832大数据查询分析是云计算中核心问题之一,自从Google在20 ... -
大数据处理方面的 7 个开源搜索引擎
2017-09-22 03:01 496大数据是一个包括一切 ... -
开源大数据查询分析引擎现状
2017-09-23 11:26 550大数据查询分析是云计算中核心问题之一,自从Google在2 ... -
elasticsearch 把很多类型都放在一个索引下面 会不会导致查询慢
2017-09-25 09:45 984主要看数据量ES索引优 ... -
腾讯大数据Hermes爱马仕的系统
2017-09-23 11:15 992腾讯大数据最近做了几件事,上线了一个官方网站http:// ... -
配置高性能Elasticsearch集群的9个小贴士
2017-09-25 10:02 592Loggly服务底层的很多 ... -
Elasticsearch与Solr
2017-09-25 16:24 552Elasticsearch简介* Elasti ... -
大数据杂谈微课堂|Elasticsearch 5.0新版本的特性与改进
2017-09-26 09:57 808Elastic将在今年秋季的 ... -
ElasticSearch性能优化策略
2017-09-26 09:51 450ElasticSearch性能优化主 ... -
ES索引优化
2017-09-19 20:39 0ES索引优化篇主要从两个方面解决问题,一是索引数据过程;二是 ... -
分词与索引的关系
2017-09-19 20:33 0分词与索引,是中文搜索里最重要的两个技术,而且两者间是密不可 ... -
Elasticsearch中的segment理解
2017-09-19 20:30 0在Elasticsearch中, 需要搞清楚几个名词,如se ...
相关推荐
它为全文检索引擎提供了大量的Java类的接口,主要提供查询引擎、索引引擎、存储管理和文本分析接口。Lucene为软件开发人员提供了一个简单易用的工具类包,方便在目标系统中实现全文检索的功能。 一、Lucene应用配置...
在这个项目中,我们将深入探讨如何将这两者结合,以实现高效的数据检索功能。 首先,我们需要了解Spring框架。Spring是一个开源的应用框架,提供了依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-...
Java中的`Analyzer`类扮演了这个角色,可以根据不同的需求定制分词规则。 2. **文档字段(Document Fields)**:每个文档都是由一个或多个字段组成的,比如标题、内容等。`Document`类用于表示这些字段及其值。 3....
接着,通过`IndexWriterConfig`配置索引写入器,并用它创建`IndexWriter`对象。接下来,遍历要索引的文件或数据源,对每一份内容使用`Document`对象存储,添加字段(如`TextField`或`StoredField`),并调用`...
这个改变影响了所有继承自`DocIdSetIterator`的类,如`DocsEnum`和`DocsAndPositionsEnum`,增强了迭代器的规范性。 4. Lucene-5127:删除了`IndexWriterConfig`中的`setTermIndexInterval`、`...
5. **IndexWriterConfig**:通过 IndexWriterConfig 类,开发者可以更方便地配置 IndexWriter,控制索引构建和更新的行为,比如设置缓存策略、合并策略等。 6. **IndexReader API 变更**:`IndexWriter.getReader` ...
2. **索引写入**:在创建索引的过程中,Lucene会使用`IndexWriter`类来管理索引的写入操作。`IndexWriter`可以添加、删除或更新文档,并负责合并段以优化性能。 3. **搜索**:一旦索引建立完成,就可以使用`...
5. **创建IndexWriterConfig**:配置写入索引的行为,如写入优化策略、缓冲大小等。 6. **创建IndexWriter**:使用`IndexWriterConfig`和索引目录创建`IndexWriter`,这是实际处理索引写入的对象。 7. **索引文档*...
接下来,我们创建一个索引管理类,用于处理文件的读取、索引的创建和更新。在`src/main/java`目录下创建对应的包结构,例如`com.example.lucene.manager.IndexManager`,并实现以下关键方法: 1. `void createIndex...
`IndexWriterConfig` 类用于配置 `IndexWriter` 的行为,例如设置使用的 Analyzer、是否开启自动合并等。 **1.1.5 Document** `Document` 是 Lucene 中表示单个文档的对象,由一个或多个 `Field` 对象组成。 **...
`IndexWriter`是Lucene中的一个类,负责管理和更新索引。通过`addDocument`方法,可以将新创建的`Document`添加到索引中。`IndexWriter`还提供了优化索引的功能,通过`optimize`方法可以合并段以提高搜索性能。 ...
例如,Elasticsearch是一个基于Lucene的企业级搜索平台,它在Lucene的基础上提供了更高级的API和集群管理功能。而Solr则是另一个流行的搜索引擎,它在Lucene之上提供了丰富的配置选项和更易用的Web界面。 总结来说...
2. 索引writer初始化:使用`IndexWriterConfig`配置并创建`IndexWriter`实例。配置参数包括分词器、内存缓冲大小、写入模式等。 3. 添加文档:调用`IndexWriter`的`addDocument()`方法将`Document`对象添加到索引中...
1. **安装与配置**:首先,你需要将 IKAnalyzer.jar 添加到项目的类路径中。这可以通过在 Maven 或 Gradle 构建文件中添加依赖,或者手动将 JAR 文件放入项目的 lib 目录来完成。 2. **创建索引**:使用 Lucene API...
确保你的开发环境支持 Java 5 或更高版本,因为 Lucene 3.0 需要这个版本的 JVM。 **2. 创建索引** 创建索引是全文检索的第一步。在 Lucene 3.0 中,使用 `IndexWriter` 类来写入文档到索引中。相比于 2.0 版本,...
使用`FSDirectory`打开一个目录,这将是我们的索引存储位置。例如: ```java FSDirectory directory = FSDirectory.open(Paths.get("indexdir")); ``` 2. **配置Analyzer** Lucene对中文处理需要特殊的...
接下来,我们需要创建一个数据模型类,这个类将被JPA映射到MySQL数据库中的表。例如,我们有一个`Article`实体类,包含标题、内容等字段: ```java @Entity public class Article { @Id @GeneratedValue(strategy...
`IKAnalyzer`是IK分词器的核心类,它实现了`org.apache.lucene.analysis.Analyzer`接口,这是Lucene搜索引擎框架中的一个关键组件,负责对输入的文本进行分析,将其转化为可搜索的索引形式。 在Java项目中,使用IK...
**标题:“如何使用Lucene的中文分词搜索”** 在信息检索和文本处理领域,Apache Lucene是一个强大的全文搜索引擎库,它...这部分代码可能涉及到JDBC操作和事务管理,具体实现会根据实际需求和数据库类型有所不同。
1. **安装与引入**: 在Java项目中使用Lucene,首先需要下载并添加Lucene的jar包到项目的类路径中,或者使用Maven或Gradle等构建工具进行依赖管理。 2. **索引文档**: 创建索引是Lucene的核心步骤,涉及分析文本、...