Lucene

入门示例步骤(步骤列出代码)
采集数据

创建Book类
private Integer id;    //图书的id

private String name;   //图书的名称

private Float price;   //图书的价格

private String pic;    //图书的图片  存的是图片的访问路径

private String desc;   //图书的描述信息

创建一个BookDao类

public class BookDao {
public List<Book> getBooks(){
    List<Book> list = new ArrayList<>();
    Connection connection = JDBCUtil.getConnection();
    String sql = "select * from book";
    try {
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()){
            Book book = new Book();
            book.setId(resultSet.getInt("id"));
            book.setName(resultSet.getString("name"));
            book.setPic(resultSet.getString("pic"));
            book.setPrice(resultSet.getFloat("price"));
            book.setDesc(resultSet.getString("description"));
            list.add(book);
        }
        resultSet.close();
        preparedStatement.close();
        connection.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return list;
}

创建一个测试类testLucene

@Test
public void getAll(){
    List<Book> books = bookDao.getBooks();
    for (Book book:books) {
        System.out.println(book.getName());
    }
}

执行结果

java 编程思想
apache lucene
mybatis
spring
solr

将数据转换成Lucene文档
修改BookDao,新增一个方法,转换数据

public List<Document> getDocument(List<Book> books){
    //第一步:创建封装数据的对象
    List<Document> documents = new ArrayList<>();
//第二步:数据对象转移
for (Book book:books) {
    //创建不同的Field对象
    Field id = new TextField("id",book.getId().toString(), Field.Store.YES);
    Field name = new TextField("name",book.getName(), Field.Store.YES);
    Field pic = new TextField("pic",book.getPic(), Field.Store.YES);
    Field price = new TextField("price",book.getPrice().toString(), Field.Store.YES);
    Field desc = new TextField("desc",book.getDesc(), Field.Store.YES);
    Document document = new Document();
    document.add(id);
    document.add(name);
    document.add(pic);
    document.add(price);
    document.add(desc);
    documents.add(document);
}
//第三步:返回数据对象
return  documents;

}
创建索引库

修改测试类,新增createIndex方法
BookDao bookDao = new BookDao();
/*
* 创建索引库需要什么?
* 1.因为创建索引库的时候需要分词,所以要创建分词器
* 2.因为索引库是一个磁盘文件,所以我们需要路径,滨崎需要写入对象
* */
@Test
public void cresteIndex(){
    //第一步:创建分词器
    Analyzer analyzer = new StandardAnalyzer();
    try {
        //第二步:创建一个目录对象
        FSDirectory directory = FSDirectory.open(new File("F://lucene"));
        //第三步:创建索引库写入对象
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,analyzer);
        IndexWriter indexWriter = new IndexWriter(directory,config);
        //第四步:写入文档数据
        indexWriter.addDocuments(bookDao.getDocument(bookDao.getBooks()));
        //第五步:关闭流
        indexWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

执行搜索
修改测试类,新增searchDocumentByIndex方法

  • 需要的条件
  • 1.因为是全文索引,所以需要分词
  • 2.需要一个查询对象
  • */
@Test
    public void SearchByIndex(){
        Analyzer analyzer = new StandardAnalyzer();
        QueryParser parser = new QueryParser("name",analyzer);
    try {
        Query query = parser.parse("java solr");
    FSDirectory directory = FSDirectory.open(new File("F://lucene"));
    IndexReader reader = DirectoryReader.open(directory);
    IndexSearcher searcher = new IndexSearcher(reader);
    TopDocs search = searcher.search(query, 10);
    ScoreDoc[] scoreDocs = search.scoreDocs;
    for (ScoreDoc scoreDoc:scoreDocs) {
        Document document = searcher.doc(scoreDoc.doc);
        System.out.println("图书的id:"+document.get("id"));
        System.out.println("图书的名字:"+document.get("name"));
        System.out.println("图书的价格:"+document.get("price"));
        System.out.println("图书的图片地址:"+document.get("pic"));
    }
} catch (IOException e) {
    e.printStackTrace();
} catch (ParseException e) {
    e.printStackTrace();
}

分别列出StringField、Sto’redField、LongField、FloatField、TextField的区别(表)

Field 数据类型Analyzed 是否分词Index是否索引Store是否存储
StringField(FieldName,FieldValue,Store.YES) 字符串NYY或N
LongField(FieldName,FieldValue,Store.YES) Long型YYY或N
FloatField(FieldName,FieldValue,Store.YES) Float型YYY或N
StoredField(FieldName,FieldValue,Store.YES) 重载方法NNY或N
TextField(FieldName,FieldValue,Store.YES) 字符串YYY或N

索引库的维护(增删改)
添加索引
修改Dao层

public int insert(Book book){
    Connection connection = JDBCUtil.getConnection();
    String sql = "insert into book (name,price,pic,description) values (?,?,?,?)";
    int i = 0;
    try {
        PreparedStatement ps = connection.prepareStatement(sql);
        ps.setString(1,book.getName());
        ps.setFloat(2,book.getPrice());
        ps.setString(3,book.getPic());
        ps.setString(4,book.getDesc());
        i = ps.executeUpdate();
        ps.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    try {
        connection.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return i; 
}

修改测试代码

public  void insert(){
    //1.插入数据
    Book book = new Book();
    book.setId(9);
    book.setName("solr入门基础");
    book.setPrice(60f);
    book.setPic("F://tupian");
    book.setDesc("这是一本关于solr基础的书");
    int insert = bookDao.insert(book);
    System.out.println(insert);

    try {
        //2.插入数据到索引
        //2.1创建分词解释器对象
        Analyzer analyzer = new StandardAnalyzer();
        FSDirectory directory = FSDirectory.open(new File("F://lucene"));
        //2.2获取索引库目录
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,analyzer);
        //2.3获得索引库写入的配置对象
        IndexWriter writer = new IndexWriter(directory,config);
        //2.4创建索引写入对象
        Field id = new StoredField("id",book.getId().toString());
        Field name = new TextField("name",book.getName(), Field.Store.YES);
        Field pic = new StoredField("pic",book.getPic());
        Field price = new TextField("price",book.getPrice().toString(), Field.Store.YES);
        Field desc = new TextField("desc",book.getDesc(), Field.Store.NO);
        Document document = new Document();
        document.add(id);
        document.add(name);
        document.add(pic);
        document.add(price);
        document.add(desc);
        //2.5写入Document对象
        writer.addDocument(document);
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}


Analyzer analyzer = new StandardAnalyzer();
QueryParser parser = new QueryParser("name",analyzer);

try {
    Query query = parser.parse("solr");

FSDirectory directory = FSDirectory.open(new File("F://lucene"));

IndexReader reader = DirectoryReader.open(directory);

IndexSearcher searcher = new IndexSearcher(reader);
TopDocs search = searcher.search(query, 10);
ScoreDoc[] scoreDocs = search.scoreDocs;
for (ScoreDoc scoreDoc:scoreDocs) {
    Document document = searcher.doc(scoreDoc.doc);
    System.out.println("图书的id:"+document.get("id"));
    System.out.println("图书的名字:"+document.get("name"));
    System.out.println("图书的价格:"+document.get("price"));
    System.out.println("图书的图片地址:"+document.get("pic"));
    System.out.println("图书的描述:"+document.get("desc"));
}

删除索引
删除solr之前,查询solr结果:

修改测试代码并执行

@Test
public void delIndex(){
    //2.插入数据到索引
    //2.1创建分词解释器对象
    Analyzer analyzer = new StandardAnalyzer();
    FSDirectory directory = null;
    try {
        directory = FSDirectory.open(new File("F://lucene"));
        //2.2获取索引库目录
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,analyzer);
        //2.3获得索引库写入的配置对象
        IndexWriter writer = new IndexWriter(directory,config);
        //2.4删除指定关键字
        writer.deleteDocuments(new Term("name","solr"));
    } catch (IOException e) {
        e.printStackTrace();
    }

}

再次测试查询solr关键字

更新索引
修改测试代码

@Test
public void updateIndex(){

try {
    //1.指定索引目录
    FSDirectory directory = FSDirectory.open(new File("F://lucene"));
    //2.创建IndexWriterConfig
    IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,new StandardAnalyzer());
    //3.创建IndexWriter
    IndexWriter writer = new IndexWriter(directory,config);
    //4.通过IndexWriter来修改索引
    //a)创建修改后的文档对象
    Document document = new Document();
    Field name = new StringField("name","updateIndex", Field.Store.YES);
    document.add(name);
    //修改指定索引为新的索引
    writer.updateDocument(new Term("name","java"),document);
    //5.关闭IndexWriter
    writer.close();
} catch (IOException e) {
    e.printStackTrace();
}

}

修改其实就是将原来的先删除,再添加一个document文档。因为我的文档中只写了nameFiled所以搜索的内容只有name其他为null;

问题9:条件查询(TermQuery、NumericRangeQuery、BooleanQuery)
1.TermQuery条件查询;
修改Dao层代码,添加一个doSearch方法

public void doSearch(Query query){
    try {
        FSDirectory directory = FSDirectory.open(new File("F://lucene"));
    IndexReader reader = DirectoryReader.open(directory);
    IndexSearcher searcher = new IndexSearcher(reader);
    TopDocs search = searcher.search(query, 10);
    ScoreDoc[] scoreDocs = search.scoreDocs;
    for (ScoreDoc scoreDoc:scoreDocs) {
        Document document = searcher.doc(scoreDoc.doc);
        System.out.println("图书的id:"+document.get("id"));
        System.out.println("图书的名字:"+document.get("name"));
        System.out.println("图书的价格:"+document.get("price"));
        System.out.println("图书的图片地址:"+document.get("pic"));
        System.out.println("图书的描述:"+document.get("desc"));
    }
} catch (IOException e) {
    e.printStackTrace();
}
}

修改测试代码

@Test
public  void queryByTermQuery(){
    Query query = new TermQuery(new Term("name","想"));
    bookDao.doSearch(query);
}

2.NumericRangeQuery条件查询;
修改测试代码
/*

  • NumericRangeQuery.newFloatRange(“price”,60f,80f,true,false);
  • 第一个参数表示要查询的域
  • 第二个表示要查询的最小值
  • 第三个表示要查询的最大值
  • 第四个表示是否包含最小值,true包含,false不包含
  • 第五个表示是否包含最大值,true包含,false不包含
  • */
@Test
    public void queryByNumricRangeQuery(){
        Query query = NumericRangeQuery.newFloatRange("price",60f,80f,true,false);
        bookDao.doSearch(query);
    } 

3.BooleanQuery
修改测试代码

@Test
public void queryBooleanQuery(){
    Query termQuery = new TermQuery(new Term("name","想"));
    Query numericRangeQuery = NumericRangeQuery.newFloatRange("price",60f,80.0f,true,false);
    BooleanQuery query = new BooleanQuery();
    query.add(termQuery, BooleanClause.Occur.MUST);
    query.add(numericRangeQuery, BooleanClause.Occur.MUST);
    bookDao.doSearch(query);
}

MultiFieldQueryParser的使用
修改测试代码

@Test
public void queryByMultiFieldQueryParser(){
    try {
        Analyzer analyzer = new StandardAnalyzer();
        String[] fields = {"name","desc"};
        MultiFieldQueryParser parser = new MultiFieldQueryParser(fields,analyzer);
        Query query = parser.parse("java");
        bookDao.doSearch(query);
    }catch (Exception e){
        e.printStackTrace();
    }
}

配置中文分词解释器
1.删除原索引库
2.导入IKAnalyzer jar包,创建索引库

@Test
public void createIndex(){
    //第一步:创建分词器
    Analyzer analyzer = new IKAnalyzer();
    try {
        //第二步:创建一个目录对象
        FSDirectory directory = FSDirectory.open(new File("F://lucene"));
        //第三步:创建索引库写入对象
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST,analyzer);
        IndexWriter indexWriter = new IndexWriter(directory,config);
        //第四步:写入文档数据
        indexWriter.addDocuments(bookDao.getDocument(bookDao.getBooks()));
        //第五步:关闭流
        indexWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3.修改测试代码

@Test
public  void queryByIKAnalyzer(){
    Query query = new TermQuery(new Term("name","数据"));
    bookDao.doSearch(query);

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值