• 需求:模糊搜索。
  • 前提:  本例中使用lucene 5.3.0
package com.shyroke.lucene;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths; 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.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableFieldType;
import org.apache.lucene.queries.function.valuesource.DualFloatFunction;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory; public class Indexer {
// 写索引
private IndexWriter indexWriter; /**
* 实例化写索引
*
* @param dir
* 保存索引的目录
* @throws IOException
*/
public Indexer(String dir) throws IOException {
Directory indexDir = new SimpleFSDirectory(Paths.get(dir)); /**
* IndexWriterConfig实例化该类的时候如果是空的构造方法,那么默认 public IndexWriterConfig() { this(new
* StandardAnalyzer()); }
*/ Analyzer analyzer=new StandardAnalyzer(); //分词器
IndexWriterConfig conf = new IndexWriterConfig(analyzer); indexWriter = new IndexWriter(indexDir, conf);
} /**
* 索引文件
*/ public void index(File file) throws Exception {
System.out.println("被索引的文件为:" + file.getCanonicalPath());
Document document = getDocument(file);
indexWriter.addDocument(document); } /**
* 从文件中获取文档
*
* @param file
* @return
* @throws IOException
*/
private Document getDocument(File file) throws IOException {
Document document = new Document(); Field contentField = new TextField("fileContents", new FileReader(file));
/**
* Field.Store.YES表示把该Field的值存放到索引文件中,提高效率,一般用于文件的标题和路径等常用且小内容小的。
*/
Field fileNameField = new TextField("fileName", file.getName(), Field.Store.YES);
Field filePathField = new TextField("filePath", file.getCanonicalPath(), Field.Store.YES); document.add(contentField);
document.add(fileNameField);
document.add(filePathField); return document;
} /**
* 创建索引
*
* @param dataFile 数据文件所在的目录
* @return 索引文件的数量
* @throws Exception
*/
public int CreateIndex(String dataFile, FileFilter filter) throws Exception { File[] files = new File(dataFile).listFiles(); for (File file : files) {
/**
* 被索引文件必须不能是 1.目录 2.隐藏 3. 不可读 4.不是txt文件,
* 否则不被索引
*/ if (!file.isDirectory() && !file.isHidden() && file.canRead() && filter.accept(file)) {
index(file);
} } return indexWriter.numDocs();
} /**
* 关闭写索引
*
* @throws IOException
*/
public void close() throws IOException {
indexWriter.close(); } }
  • 这个类用来遍历数据文件夹,生成索引文件。
  • 对特定项搜索

public class SearchTest {

    private IndexWriter writer;
private IndexSearcher search;
private IndexReader reader;
private String indexDir = "E:\\\\lucene4\\\\index";
private String dataDir = "E:\\\\lucene4\\\\data"; @Before
public void setUp() throws Exception {
Indexer indexer = new Indexer(indexDir);
indexer.CreateIndex(dataDir, new FileFilter());
/**
* 一定要把IndexWriter实例关闭,否则segments_1文件不会生成。
*/
indexer.close(); Directory indexDirectory = FSDirectory.open(Paths.get(indexDir));
reader = DirectoryReader.open(indexDirectory);
search = new IndexSearcher(reader);
} @After
public void tearDown() throws Exception {
reader.close();
} /**
* 对特定项搜索
* @throws IOException
*/
@Test
public void textTermQuery() throws IOException {
System.out.println("--------------------");
String key = "particular";
Term t = new Term("fileContents", key);
Query query = new TermQuery(t);
TopDocs hits = search.search(query, 10);
System.out.println("匹配 '" + key + "',总共查询到" + hits.totalHits + "个文档"); for (ScoreDoc scoreDoc : hits.scoreDocs) {
Document doc = search.doc(scoreDoc.doc);
System.out.println(doc.get("filePath"));
}
} }
  • 注意:上述代码中的橙色标注代码,一定要把IndexWriter实例关闭,否则segments_1文件不会生成。

结果:

  • 解析:对特定项搜索的方法是以搜索关键字作为单位查询,如果把关键字key改为key="particul" ,则结果如下,无法匹配到particular:

  • 解析查询表达式

/**
* 解析查询表达式,在要搜索的关键字中可以使用AND OR ~ * ?等
* AND 与 OR 或 ~相近
* AND和OR只能大写
* @throws ParseException
* @throws IOException
*/
@Test
public void testQueryParse() throws ParseException, IOException {
System.out.println("--------------------");
Analyzer analyzer=new StandardAnalyzer();
QueryParser parser=new QueryParser("fileContents", analyzer);
String key="Source* AND Derivati*";
Query query=parser.parse(key);
TopDocs hits =search.search(query, 10); System.out.println("匹配 '" + key + "',总共查询到" + hits.totalHits + "个文档"); for (ScoreDoc scoreDoc : hits.scoreDocs) {
Document doc = search.doc(scoreDoc.doc);
System.out.println(doc.get("filePath"));
}
}

结果:

  • 查看LICENSE.txt文档,

(五)lucene之特定项搜索和查询表达式的更多相关文章

  1. 记一次企业级爬虫系统升级改造(五):基于JieBaNet+Lucene.Net实现全文搜索

    实现效果: 上一篇文章有附全文搜索结果的设计图,下面截一张开发完成上线后的实图: 基本风格是模仿的百度搜索结果,绿色的分页略显小清新. 目前已采集并创建索引的文章约3W多篇,索引文件不算太大,查询速度 ...

  2. Lucene.Net 站内搜索

    Lucene.Net 站内搜索 一  全文检索: like查询是全表扫描(为性能杀手)Lucene.Net搜索引擎,开源,而sql搜索引擎是收费的Lucene.Net只是一个全文检索开发包(只是帮我们 ...

  3. C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例

    C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...

  4. 基于JieBaNet+Lucene.Net实现全文搜索

    实现效果: 上一篇文章有附全文搜索结果的设计图,下面截一张开发完成上线后的实图: 基本风格是模仿的百度搜索结果,绿色的分页略显小清新. 目前已采集并创建索引的文章约3W多篇,索引文件不算太大,查询速度 ...

  5. Lucene.net站内搜索—6、站内搜索第二版

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  6. Lucene.net站内搜索—5、搜索引擎第一版实现

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  7. Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  8. Lucene.net站内搜索—3、最简单搜索引擎代码

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  9. Lucene.net站内搜索—2、Lucene.Net简介和分词

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

随机推荐

  1. LeetCode 209. 长度最小的子数组(Minimum Size Subarray Sum)

    题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...

  2. qt mvc3

    前面两节讲的model是一维的,这次开始二维的也就是我们常说的Table,相对与list,我们多了一个列的概念. 下面讲解一个例子.我先说明一下我们这个例子,在程序目录下,我们有一个文本文件,其中存放 ...

  3. linux几种传输方式与拷贝方式的性能分析

    本文记录linux系统中文件传输的多种方式,留作备忘.linux中文件传输的方式有ftp,scp,rsync,rz,sz等,但各个工具的功能又有所区别: FTP : FTP是文件服务器,可实现文件的上 ...

  4. 几种常见空间滤波器MATLAB实现

    本文链接:https://blog.csdn.net/LYduring/article/details/80443573 一.目的实现算术均值滤波器.几何均值滤波器.中值滤波器.修正的阿尔法均值滤波器 ...

  5. <HTML/CSS>BFC原理剖析

    本文讲了BFC的概念是什么: BFC的约束规则:咋样才能触发生成新的BFC:BFC在布局中的应用:防止margin重叠(塌陷,以最大的为准): 清除内部浮动:自适应两(多)栏布局. 1. BFC是什么 ...

  6. List&Set

    List a.普通for循环, 使用get()逐个获取 b.调用iterator()方法得到Iterator, 使用hasNext()和next()方法 c.增强for循环, 只要可以使用Iterat ...

  7. 使用Docker快速搭建Tensorflow开发环境

    当我刚开始学习使用scikit-learn时,总是会出现各种各样的包依赖问题,兜兜转转了一遍才全部安装好,现在的机器学习算法开发者大都使用tensorflow.pytorch来实现自己的想法,但依然会 ...

  8. ARM程序的RO段、RW段和ZI段 --Image

    Limit 含义了解RO,RW和ZI需要首先了解以下知识:ARM程序的组成此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别. ...

  9. 最简易的python web框架的后端实现

    1.源代码 #!/usr/bin/python #encoding=utf-8 from flask import json, Flask, request app = Flask(__name__) ...

  10. C++线程互斥、同步

     一.线程互斥 如果多个线程需要访问且可能修改同一个变量,那么需要加锁,保证同一时刻只有一个线程可以访问,这个动作即最小“原子操作” 方式1: 使用c++提供的类mutex,lock,unlock即可 ...