Lucene索引库维护(CRUD操作)

 

1.Lucene索引库维护

  • 说明:数据保存在关系数据库,需要实现增删改查操作。索引数据保存在索引库,也需要实现增删改查操作。

1.1 添加索引

public class CrudTest {

    private IndexWriter indexWriter;

    @Before
    public void before() throws Exception{
        // 创建分词器
        IKAnalyzer analyzer = new IKAnalyzer();
        // 创建写索引需要的配置信息对象
        IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);
        iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        // 创建索引库存储的目录
        Directory directory = FSDirectory.open(new File("F:\\index"));
        // 创建IndexWriter对象,操作索引库
        indexWriter = new IndexWriter(directory, iwc);
    }

    /** 添加文档到索引库 */
    @Test
    public void save() throws Exception{

        // 创建文档对象
        Document document = new Document();
        // 文档添加Field
        document.add(new StringField("id", "5", Field.Store.YES));
        document.add(new TextField("name", "lucene solr dubbo", Field.Store.YES));

        // 添加到索引库(根据Field创建索引, 保存文档到索引库)
        indexWriter.addDocument(document);
        // 提交事务
        indexWriter.commit();

    }
}

1.2 删除索引

1.2.1 根据Term删除索引

  1. 创建分词器对象(Analyzer),用于分词。
  2. 创建索引库配置对象(IndexWriterConfig),配置索引库。
  3. 创建索引库目录对象(Directory),指定索引库位置。
  4. 创建索引库操作对象(IndexWriter),操作索引库。
  5. 创建条件对象(Term)。
  6. 使用IndexWriter对象,执行删除。
  7. 释放资源。

1.2.2 删除全部索引

  1.  创建分析器对象(Analyzer),用于分词
  2. 创建索引库配置对象(IndexWriterConfig),配置索引库
  3. 创建索引库目录对象(Directory),指定索引库的位置
  4. 创建索引库操作对象(IndexWriter),操作索引库
  5. 使用IndexWriter,执行删除
public class CrudTest {

    private IndexWriter indexWriter;

    @Before
    public void before() throws Exception{
        // 创建分词器
        IKAnalyzer analyzer = new IKAnalyzer();
        // 创建写索引需要的配置信息对象
        IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);
        iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        // 创建索引库存储的目录
        Directory directory = FSDirectory.open(new File("F:\\index"));
        // 创建IndexWriter对象,操作索引库
        indexWriter = new IndexWriter(directory, iwc);
    }

    /** 修改索引库中的文档(如果没有Term词就会做添加) */
    @Test
    public void update() throws Exception{

        // 创建文档对象
        Document document = new Document();
        // 文档添加Field
        document.add(new StringField("id", "10", Field.Store.YES));
        document.add(new TextField("bookName", "Lucene全文检索", Field.Store.YES));

        // 创建Term词
        Term term = new Term("id", "10");

        // 修改索引库中文档(索引与文档同时修改)
        indexWriter.updateDocument(term, document);
        // 提交事务
        indexWriter.commit();
    }


    /** 删除索引库中的文档(索引也会删除) */
    @Test
    public void delete() throws Exception{

        // 创建Term词
        Term term = new Term("id", "4");
        // 删除索引库中文档(索引与文档同时删除)
        indexWriter.deleteDocuments(term);
        // 提交事务
        indexWriter.commit();
    }

    /** 删除索引库中全部的文档 */
    @Test
    public void deleteAll() throws Exception{

        // 删除索引库中文档
        indexWriter.deleteAll();
        // 提交事务
        indexWriter.commit();
    }

}

 1.3 更新索引

说明:Lucene是根据Term执行索引的更新,先根据Term执行搜索,搜索到执行更新;搜索不到执行添加。

  • 创建分析器对象(Analyzer),用于分词
  • 创建索引库配置对象(IndexWriterConfig),配置索引库
  • 创建索引库目录对象(Directory),指定索引库的位置
  • 创建索引库操作对象(IndexWriter),操作索引库
  • 创建文档对象(Document)
  • 创建条件对象(Term)
  • 使用IndexWriter,执行更新
  • 提交事务
  • 释放资源
/** 更新索引 */
@Test
public void updateIndex() throws Exception{
    // 创建分析器,用于分词
    Analyzer analyzer = new IKAnalyzer();
    // 创建索引库配置信息对象
    IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_10_3,analyzer);
    // 创建索引库存储目录
    Directory directory = FSDirectory.open(new File("F:\\index"));
    // 创建IndexWriter,操作索引库
    IndexWriter indexWriter = new IndexWriter(directory, iwc);

    // 创建文档对象
    Document doc = new Document();
    // 文档添加域
    doc.add(new StringField("id", "9529", Field.Store.YES));
    doc.add(new TextField("name", "lucene solr dubbo zookeeper", Field.Store.YES));
    // 创建查询条件对象
    Term term = new Term("name","lucene");
    // 使用indexWriter对象,执行更新
    indexWriter.updateDocument(term, doc);
    // 提交事务
    indexWriter.commit();
    // 关闭,释放资源
    indexWriter.close();
}

2. Lucene搜索API

说明:在搜索中关心Query对象的创建。

2.1 query对象的两种创建方式

Lucene索引库维护(CRUD操作)_第1张图片

使用TermQuery

需求:查询图书名称域中包含有java的图书。

/** 定义搜索方法 */
private void search(Query query) throws Exception{
    // 查询语法
    System.out.println("查询语法:" + query);
    // 创建索引库存储目录
    Directory directory = FSDirectory.open(new File("F:\\index"));
    // 创建IndexReader读取索引库对象
    IndexReader indexReader = DirectoryReader.open(directory);
    // 创建IndexSearcher,执行搜索索引库
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    /**
     * search方法:执行搜索
     * 参数一:查询对象
     * 参数二:指定搜索结果排序后的前n个(前10个)
     */
    TopDocs topDocs = indexSearcher.search(query, 10);
    // 处理结果集
    System.out.println("总命中的记录数:" + topDocs.totalHits);
    // 获取搜索到得文档数组
    ScoreDoc[] scoreDocs = topDocs.scoreDocs;
    // ScoreDoc对象:只有文档id和分值信息
    for (ScoreDoc scoreDoc : scoreDocs){
        System.out.println("-------华丽分割线----------");
        System.out.println("文档id: " + scoreDoc.doc
                + "\t文档分值:" + scoreDoc.score);
        // 根据文档id获取指定的文档
        Document doc = indexSearcher.doc(scoreDoc.doc);
        System.out.println("图书Id:" + doc.get("id"));
        System.out.println("图书名称:" + doc.get("bookName"));
        System.out.println("图书价格:" + doc.get("bookPrice"));
        System.out.println("图书图片:" + doc.get("bookPic"));
        System.out.println("图书描述:" + doc.get("bookDesc"));
    }
    // 释放资源
    indexReader.close();
}

 

/**
 * TermQuery关键词查询
 * 需求:查询图书名称域中包含有java的图书。
 */
@Test
public void testTermQuery() throws Exception{
    // 创建查询对象
    TermQuery q = new TermQuery(new Term("bookName","java"));
    // 执行搜索
    search(q);
}

使用NumericRangeQuery

需求:查询图书价格在80到100之间的图书。

不包含边界值:

/**
 * NumericRangeQuery数值范围查询
 * 需求:查询图书价格在80到100之间的图书
 */
@Test
public void testNumericRangeQuery() throws Exception{
    // 创建查询对象
    /**
     * 参数说明
     *  field:域的名称
     *  min:最小范围边界值
     *  max:最大范围边界值
     *  minInclusive:是否包含最小边界值
     *  maxInclusive:是否包含最大边界值
     */
    Query q = NumericRangeQuery.newDoubleRange("bookPrice",
            80d, 100d, false, false);
    // 执行搜索
    search(q);
}

包含边界值:

/**
 * NumericRangeQuery数值范围查询
 * 需求:查询图书价格在80到100之间的图书
 */
@Test
public void testNumericRangeQuery() throws Exception{
    // 创建查询对象
    /**
     * 参数说明
     *  field:域的名称
     *  min:最小范围边界值
     *  max:最大范围边界值
     *  minInclusive:是否包含最小边界值
     *  maxInclusive:是否包含最大边界值
     */
    Query q = NumericRangeQuery.newDoubleRange("bookPrice",
            80d, 100d, true, true);
    // 执行搜索
    search(q);
}

使用BooleanQuery

 需求:查询图书名称域中包含有java的图书,并且价格在80到100之间(包含边界值)

/**
 * BooleanQuery布尔查询
 * 需求:查询图书名称域中包含有java的图书,并且价格在80到100之间(包含边界值)。
 */
@Test
public void testBooleanQuery() throws Exception{
    // 创建查询对象一
    TermQuery q1 = new TermQuery(new Term("bookName", "java"));
    // 创建查询对象二
    Query q2 = NumericRangeQuery.newDoubleRange("bookPrice",
            80d, 100d, true, true);
    // 创建组合查询条件对象
    BooleanQuery q = new BooleanQuery();
    q.add(q1, BooleanClause.Occur.MUST);
    q.add(q2, BooleanClause.Occur.MUST);
    // 执行搜索
    search(q);
}

 2.1.2 使用QueryParser查询解析器

2.1.2.1表达式语法

  • 关键词查询:fieldName:关键词,比如:bookName:lucene
  • 范围查询:fieldName:{最小值 TO 最大值],比如:price:{80 TO 100]。
  • 组合查询:

Occur.MUST搜索条件必须满足,相当于AND

+

Occur.SHOULD搜索条件可选,相当于OR

Occur.MUST_NOT搜索条件不能满足,相当于NOT非

-

 

使用QueryParser

需求:查询图书名称域中包含有java,并且图书名称域中包含有lucene的图书

/**
 * 使用QueryParser
 * 需求:查询图书名称域中包含有java,并且图书名称域中包含有lucene的图书
 */
@Test
public void testQueryParser() throws Exception{
    // 创建分析器,用于分词
    Analyzer analyzer = new IKAnalyzer();
    // 创建QueryParser解析对象
    QueryParser queryParser = new QueryParser("bookName",analyzer);
    // 解析表达式,创建Query对象
    // +bookName:java +bookName:lucene
    Query q = queryParser.parse("bookName:java AND bookName:lucene");
    // 执行搜索
    search(q);
}

 

你可能感兴趣的:(Solr,Lucene)