进入过后,我们可以看到下图显示的内容,选择 content 点击 show top items 可以看到右侧的索引数据,这里根据分词器的不同,索引的结果是不一样的,阿粉这里采用的分词器就是标准的分词器,小伙伴们可以根据自己的要求选择适合自己的分词器即可。
搜索数据
数据已经索引成功了,接下来我们就需要根据条件进行数据的搜索了,我们创建一个 LuceneSearchUtil.java 来操作数据。
import org.apache.commons.collections.MapUtils; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.*; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.springframework.beans.factory.annotation.Value; import java.io.IOException; import java.nio.file.Paths; import java.util.Map; public class LuceneSearchUtil { private static String INDEX_PATH = "/opt/lucene/demo"; private static IndexSearcher searcher; public static LuceneSearchUtil getInstance() { return LuceneSearchUtil.SingletonHolder.searchUtil; } private static class SingletonHolder { public final static LuceneSearchUtil searchUtil = new LuceneSearchUtil(); } private LuceneSearchUtil() { this.initSearcher(); } private void initSearcher() { Directory directory; try { directory = FSDirectory.open(Paths.get(INDEX_PATH)); DirectoryReader reader = DirectoryReader.open(directory); searcher = new IndexSearcher(reader); } catch (IOException e) { e.printStackTrace(); } } public TopDocs searchByMap(Map<String, Object> queryMap) throws Exception { if (null == searcher) { this.initSearcher(); } if (MapUtils.isNotEmpty(queryMap)) { BooleanQuery.Builder builder = new BooleanQuery.Builder(); queryMap.forEach((key, value) -> { if (value instanceof String) { Query queryString = new PhraseQuery(key, (String) value); // Query queryString = new TermQuery(new Term(key, (String) value)); builder.add(queryString, BooleanClause.Occur.MUST); } }); return searcher.search(builder.build(), 10); } return null; } }
在 demo.java 中增加搜索代码如下:
//查询数据 Map<String, Object> map = new HashMap<>(); map.put("title", "Java 极客技术"); // map.put("title", "极客技术"); // map.put("content", "最"); LuceneSearchUtil searchUtil = LuceneSearchUtil.getInstance(); TopDocs topDocs = searchUtil.searchByMap(map); System.out.println(topDocs.totalHits);
运行结果如下,表示搜索到了两条。
通过可视化工具我们可以看到 title 为"Java 极客技术"确实是有两条记录,而且我们也确认只插入了两条数据。注意这里如果根据其他字符去查询可能查询不出来,因为阿粉这里的分词器采用的是默认的分词器,小伙伴可以根据自身的情况采用相应的分词器。
至此我们可以索引和搜索数据了,不过这还是简单的入门操作,对于不同类型的字段,我们需要使用不同的查询方式,而且根据系统的特性我们需要使用特定的分词器,默认的标准分词器不一定符合我们的使用场景。而且我们索引数据的时候也需要根据字段类型进行不同 Field 的设定。上面的案例只是 demo 并不能在生产上使用,搜索引擎在互联网行业是领头羊,很多先进的互联网技术都是从搜索引擎开始发展的。
相关的代码阿粉已经放到 GitHub 上了,公众号回复【源码仓库】即可获得。