入门示例步骤(步骤列出代码)
采集数据
创建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) 字符串 | N | Y | Y或N |
LongField(FieldName,FieldValue,Store.YES) Long型 | Y | Y | Y或N |
FloatField(FieldName,FieldValue,Store.YES) Float型 | Y | Y | Y或N |
StoredField(FieldName,FieldValue,Store.YES) 重载方法 | N | N | Y或N |
TextField(FieldName,FieldValue,Store.YES) 字符串 | Y | Y | Y或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);
}