Lucene的条件查询
程序员文章站
2022-07-09 09:55:03
...
MainTest文件
因为没有做Lucene的util,比较冗杂
package lucene;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.hunspell.Dictionary;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FloatDocValuesField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.BooleanClause.Occur;
import org.junit.Test;
import com.seehope.lucene.dao.BookDao;
import com.seehope.lucene.pojo.Book;
public class MainTest {
//···生成lucene索引库
public void test() {
BookDao BookDao=new BookDao();
List<Book> books=BookDao.queryAllBook();
List<Document> documents=new ArrayList<Document>();
Document document=null;
int i=0;
for (Book book : books) {
document=new Document();
/**
* 是否分词
* 是否建立索引(该域有没有可能成为查询条件)有可能成为查询条件的类建立索引
* 是否储存是否要将file的value存在文件中。如果需要直接从lucene中得到数据的字段,才需要储存
*/
//id不需要分词,要索引和储存
Field id=new StoredField("id",book.getId().toString());
//需要分词,需要索引,需要储存
Field name=new TextField("name",book.getName(),Store.YES);
//lucene 对数值类型有特殊的分词要求 要储存 要索引
document.add(new FloatPoint("price", book.getPrice()));
document.add(new FloatDocValuesField("prive", book.getPrice()));//储存
document.add(new StoredField("prive", book.getPrice()));//索引
//不分词,不索引,要储存
Field pic=new StoredField("pic",book.getPic());
//分词,索引,不储存
Field description=new TextField("description",book.getDescription(),Store.NO);
document.add(new TextField("index",""+(++i)+"",Store.YES));
document.add(id);
document.add(name);
document.add(pic);
document.add(description);
documents.add(document);
Analyzer analyzer=new StandardAnalyzer();
try {
Directory dictionary=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
IndexWriterConfig config=new IndexWriterConfig(analyzer);
IndexWriter indexWriter=new IndexWriter(dictionary, config);
for (Document doc : documents) {
indexWriter.addDocument(doc);
}
indexWriter.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
//删除 ByTerm
public void deleteDocumentByTerm() throws IOException {
Analyzer analyzer=new StandardAnalyzer();
Directory dictionary=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
IndexWriterConfig config=new IndexWriterConfig(analyzer);
IndexWriter indexWriter=new IndexWriter(dictionary, config);
System.out.println("有: "+indexWriter.deleteDocuments
(new Term("index","1"))+"条记录被删除");
indexWriter.close();
}
//更新 比较low··它是先删除再加进去
public void updateDocumentByTerm() throws IOException {
Analyzer analyzer=new StandardAnalyzer();
Directory dictionary=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
IndexWriterConfig config=new IndexWriterConfig(analyzer);
IndexWriter indexWriter=new IndexWriter(dictionary, config);
Document document=new Document();
document.add(new TextField("index", "1",Store.YES));
System.out.println("有: "+indexWriter.updateDocument
(new Term("index","2"),document)+"条记录被更新");
indexWriter.close();
}
//查询
public void showSearch() throws IOException, ParseException {
Analyzer analyzer=new StandardAnalyzer();
Directory directory=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
QueryParser parser=new QueryParser("description", analyzer);
Query query=parser.parse("description:java AND lucene");
IndexReader indexReader=DirectoryReader.open(directory);
IndexSearcher indexSearcher=new IndexSearcher(indexReader);
TopDocs topDoc=indexSearcher.search(query, 10);
ScoreDoc[] scoreDocs=topDoc.scoreDocs;
System.out.println("当前查询语句中 击中了多少条记录:"+topDoc.totalHits);
for (ScoreDoc scoDoc : scoreDocs) {
int docid=scoDoc.doc;
Document document=indexSearcher.doc(docid);
System.out.println("文档id:"+docid);
System.out.println(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("description"));
}
}
//对索引进行查询
public void doSearch(Query query) throws IOException {
Analyzer analyzer=new StandardAnalyzer();
Directory directory=FSDirectory.open(Paths.get(new File("lucene").getAbsolutePath()));
IndexReader indexReader=DirectoryReader.open(directory);
IndexSearcher indexSearcher=new IndexSearcher(indexReader);
TopDocs topDoc=indexSearcher.search(query, 10);
ScoreDoc[] scoreDocs=topDoc.scoreDocs;
System.out.println("当前查询语句中 击中了多少条记录:"+topDoc.totalHits);
for (ScoreDoc scoDoc : scoreDocs) {
int docid=scoDoc.doc;
Document document=indexSearcher.doc(docid);
System.out.println("文档id:"+docid);
System.out.println(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("description"));
}
}
//靠term查询 分词查询
public void queryBocumentByTerm() throws IOException {
Query query=new TermQuery(new Term("id","3"));
System.out.println(query);
doSearch(query);
}
//靠number 查询 price的【10,100)区间
//根据FloatPoint.nextDown决定是不是开或者闭区间
public void queryDocumentByNumberQuery() throws IOException {
Query query=FloatPoint.newRangeQuery("price", 10f, FloatPoint.nextDown(100f));
System.out.println(query);
doSearch(query);
}
//根据是否满足多条件查询 SHOULD或(多条件有一个符合就行) MUST和(多条件必须符合)
public void queryDocumentByBooleanQuery() throws IOException {
Query query1=FloatPoint.newRangeQuery("price", 10f, FloatPoint.nextDown(100f));
Query query2=new TermQuery(new Term("id","3"));
BooleanQuery query=new BooleanQuery.Builder().add(query1,Occur.MUST)
.add(query2,Occur.MUST).build();
doSearch(query);
}
//符合两个域名同一个关键字
@Test
public void multiFeildQueryParser() throws IOException, ParseException {
String[] fields= {"name","discription"};
QueryParser parser=new MultiFieldQueryParser(fields, new StandardAnalyzer());
Query query=parser.parse("java");
System.out.println(query);
doSearch(query);
}
/**
* 感觉有点万能
* 1.域名:搜索关键字
* content:java (域名content : 关键字java)
* 2.范围查询
* 域名:【最小值 TO 最大值】 比如说 size:[1 TO 100]
* 3.组合条件查询
* -price:[10.0 TO 99.99999] name:spring 必须不符合第一个条件
* +price:[10.0 TO 99.99999] +name:spring 必须符合第两个条件
* price:[10.0 TO 99.99999] name:spring 符合第一个条件或者符合第二个条件
* 4.两个域名同一个关键字
* name:java discription:java (或的意思)
* @throws ParseException
* @throws IOException
*
*/
public void queryDocumentByQueryParser() throws ParseException, IOException {
QueryParser parser=new QueryParser("price",new StandardAnalyzer());
Query query=parser.parse("+price:[10.0 TO 99.99999] +name:spring");
System.out.println(query);
doSearch(query);
}
}
BookDao
package com.seehope.lucene.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.seehope.lucene.pojo.Book;
public class BookDao {
public List<Book> queryAllBook(){
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<Book> books=new ArrayList<Book>();
String sql="select * from book";
Connection connection;
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/lecene", "root", "123456");
PreparedStatement preparedStatement=connection.prepareStatement(sql);
ResultSet set=preparedStatement.executeQuery();
while(set.next()) {
Book book=new Book(set.getInt("id"),set.getString("name"),set.getFloat("price"),set.getString("pic"),set.getString("description"));
books.add(book);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return books;
}
}
Book
package com.seehope.lucene.pojo;
import java.io.Serializable;
import org.apache.lucene.document.IntRange;
public class Book implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Float price;
private String pic;
private String description;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
@Override
public String toString() {
return "Book [id=" + id + ", name=" + name + ", price=" + price + ", pic=" + pic + ", description="
+ description + "]";
}
public Book(Integer id, String name, Float price, String pic, String description) {
super();
this.id = id;
this.name = name;
this.price = price;
this.pic = pic;
this.description = description;
}
public Book(String name, Float price, String pic, String description) {
super();
this.name = name;
this.price = price;
this.pic = pic;
this.description = description;
}
public Book() {
super();
}
}
pom.xml的依赖(搭建环境)
<dependencies>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-core -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>7.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-queryparser -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>7.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.lucene/lucene-analyzers-common -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>7.4.0</version>
</dependency>
</dependencies>
上一篇: 刘邦出身低,为什么那么多人愿意帮他?