二、lucene2.4的增删改查及其查询语法

来源:互联网 发布:软件图标在线制作 编辑:程序博客网 时间:2024/06/06 03:23

1、工程结构图


2、排序的几种方式

0

3、增删改查索引

package cn.hj.lucene.dao;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import jeasy.analysis.MMAnalyzer;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.NumberTools;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.Term;import org.apache.lucene.index.IndexWriter.MaxFieldLength;import org.apache.lucene.queryParser.MultiFieldQueryParser;import org.apache.lucene.queryParser.QueryParser;import org.apache.lucene.search.Filter;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;import org.apache.lucene.search.RangeFilter;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.Sort;import org.apache.lucene.search.SortField;import org.apache.lucene.search.TopDocs;import org.apache.lucene.search.highlight.Formatter;import org.apache.lucene.search.highlight.Fragmenter;import org.apache.lucene.search.highlight.Highlighter;import org.apache.lucene.search.highlight.QueryScorer;import org.apache.lucene.search.highlight.Scorer;import org.apache.lucene.search.highlight.SimpleFragmenter;import org.apache.lucene.search.highlight.SimpleHTMLFormatter;public class IndexDao {String indexPath = "D:\\Workspaces\\lucenedemo\\luceneIndex";// Analyzer analyzer = new StandardAnalyzer();Analyzer analyzer = new MMAnalyzer();// 词库分词/** * 添加/创建索引 *  * @param doc */public void save(Document doc) {IndexWriter indexWriter = null;try {indexWriter = new IndexWriter(indexPath, analyzer, MaxFieldLength.LIMITED);indexWriter.addDocument(doc);} catch (Exception e) {throw new RuntimeException(e);} finally {try {indexWriter.close();} catch (Exception e) {e.printStackTrace();}}}/** * Term是搜索的最小单位,代表某个 Field 中的一个关键词,如:<title, lucene> *  * new Term( "title", "lucene" ); *  * new Term( "id", "5" ); *  * new Term( "id", UUID ); *  * @param term */public void delete(Term term) {IndexWriter indexWriter = null;try {indexWriter = new IndexWriter(indexPath, analyzer, MaxFieldLength.LIMITED);indexWriter.deleteDocuments(term);} catch (Exception e) {throw new RuntimeException(e);} finally {try {indexWriter.close();} catch (Exception e) {e.printStackTrace();}}}/** * 更新索引 *  * <pre> * indexWriter.deleteDocuments(term); * indexWriter.addDocument(doc); * </pre> *  * @param term * @param doc */public void update(Term term, Document doc) {IndexWriter indexWriter = null;try {indexWriter = new IndexWriter(indexPath, analyzer, MaxFieldLength.LIMITED);indexWriter.updateDocument(term, doc);} catch (Exception e) {throw new RuntimeException(e);} finally {try {indexWriter.close();} catch (Exception e) {e.printStackTrace();}}}/** * <pre> * totalPage = recordCount / pageSize; * if (recordCount % pageSize > 0) * totalPage++; * </pre> *  * @param queryString * @param firstResult * @param maxResults * @return */public QueryResult search(String queryString, int firstResult, int maxResults) {try {// 1,把要搜索的文本解析为 QueryString[] fields = { "name", "content" };Map<String, Float> boosts = new HashMap<String, Float>();boosts.put("name", 3f);//数字越到权重越高// boosts.put("content", 1.0f); 默认为1.0fQueryParser queryParser = new MultiFieldQueryParser(fields, analyzer, boosts);Query query = queryParser.parse(queryString);return search(query, firstResult, maxResults);} catch (Exception e) {throw new RuntimeException(e);}}public QueryResult search(Query query, int firstResult, int maxResults) {IndexSearcher indexSearcher = null;try {// 2,进行查询indexSearcher = new IndexSearcher(indexPath);Filter filter = new RangeFilter("size", NumberTools.longToString(200), NumberTools.longToString(1000), true, true);// ========== 排序Sort sort = new Sort();sort.setSort(new SortField("size")); // 默认为升序// sort.setSort(new SortField("size", true));// ==========TopDocs topDocs = indexSearcher.search(query, filter, 10000, sort);int recordCount = topDocs.totalHits;List<Document> recordList = new ArrayList<Document>();// ============== 准备高亮器Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");Scorer scorer = new QueryScorer(query);Highlighter highlighter = new Highlighter(formatter, scorer);Fragmenter fragmenter = new SimpleFragmenter(50);highlighter.setTextFragmenter(fragmenter);// ==============// 3,取出当前页的数据int end = Math.min(firstResult + maxResults, topDocs.totalHits);for (int i = firstResult; i < end; i++) {ScoreDoc scoreDoc = topDocs.scoreDocs[i];int docSn = scoreDoc.doc; // 文档内部编号Document doc = indexSearcher.doc(docSn); // 根据编号取出相应的文档// =========== 高亮// 返回高亮后的结果,如果当前属性值中没有出现关键字,会返回 nullString hc = highlighter.getBestFragment(analyzer, "content", doc.get("content"));if (hc == null) {String content = doc.get("content");int endIndex = Math.min(50, content.length());hc = content.substring(0, endIndex);// 最多前50个字符}doc.getField("content").setValue(hc);// ===========recordList.add(doc);}// 返回结果return new QueryResult(recordCount, recordList);} catch (Exception e) {throw new RuntimeException(e);} finally {try {indexSearcher.close();} catch (IOException e) {e.printStackTrace();}}}}

4、增删改查的测试

package cn.hj.lucene.dao;import org.apache.lucene.document.Document;import org.apache.lucene.index.Term;import org.junit.Test;import cn.hj.lucene.utils.File2DocumentUtils;public class IndexDaoTest {String filePath = "D:\\Workspaces\\lucenedemo\\luceneDatasource\\IndexWriter addDocument's a javadoc .txt";String filePath2 = "D:\\Workspaces\\lucenedemo\\luceneDatasource\\小笑话_总统的房间 Room .txt";IndexDao indexDao = new IndexDao();@Testpublic void testSave() {Document doc = File2DocumentUtils.file2Document(filePath);doc.setBoost(3f);indexDao.save(doc);Document doc2 = File2DocumentUtils.file2Document(filePath2);// doc2.setBoost(1.0f);indexDao.save(doc2);}@Testpublic void testDelete() {Term term = new Term("path", filePath);indexDao.delete(term);}@Testpublic void testUpdate() {Term term = new Term("path", filePath);Document doc = File2DocumentUtils.file2Document(filePath);doc.getField("content").setValue("这是更新后的文件内容");indexDao.update(term, doc);}@Testpublic void testSearch() {// String queryString = "IndexWriter";// String queryString = "房间";// String queryString = "笑话";String queryString = "room";// String queryString = "content:绅士";QueryResult qr = indexDao.search(queryString, 0, 10);System.out.println("总共有【" + qr.getRecordCount() + "】条匹配结果");for (Document doc : qr.getRecordList()) {File2DocumentUtils.printDocument(doc);}}}

5、分页时所用到的bean

package cn.hj.lucene.dao;import java.util.List;import org.apache.lucene.document.Document;public class QueryResult {private int recordCount;private List<Document> recordList;public QueryResult(int recordCount, List<Document> recordList) {super();this.recordCount = recordCount;this.recordList = recordList;}public int getRecordCount() {return recordCount;}public void setRecordCount(int recordCount) {this.recordCount = recordCount;}public List<Document> getRecordList() {return recordList;}public void setRecordList(List<Document> recordList) {this.recordList = recordList;}}

6、lucene的查询语法

package cn.hj.lucene.query;import org.apache.lucene.document.Document;import org.apache.lucene.document.NumberTools;import org.apache.lucene.index.Term;import org.apache.lucene.search.BooleanQuery;import org.apache.lucene.search.PhraseQuery;import org.apache.lucene.search.Query;import org.apache.lucene.search.RangeQuery;import org.apache.lucene.search.TermQuery;import org.apache.lucene.search.WildcardQuery;import org.apache.lucene.search.BooleanClause.Occur;import org.junit.Test;import cn.hj.lucene.dao.IndexDao;import cn.hj.lucene.dao.QueryResult;import cn.hj.lucene.utils.File2DocumentUtils;public class QueryTest {IndexDao indexDao = new IndexDao();/** * 查询并且打印结果 * @param query */private void queryAndPrintResult(Query query) {QueryResult qr = indexDao.search(query, 0, 100);System.out.println("总共有【"+qr.getRecordCount()+"】条匹配结果");for(Document doc : qr.getRecordList()){File2DocumentUtils.printDocument(doc);}}/** * 关键字查询 */@Testpublic void testTermQuery(){Term term = new Term("name","room");Query query = new TermQuery(term);queryAndPrintResult(query);}/** * 范围查询 * 索引和搜索的时候搜索参数需要有一个相同的宽度 * 包含边界:size:[0000000000001e TO 000000000000rs] *  * 不包含边界:size:{0000000000001e TO 000000000000rs} */@Testpublic void testRangeQuery() {Term lowerTerm = new Term("size", NumberTools.longToString(50));Term upperTerm = new Term("size", NumberTools.longToString(1000));Query query = new RangeQuery(lowerTerm, upperTerm, false);queryAndPrintResult(query);}// public static void main(String[] args) {// System.out.println(Long.MAX_VALUE);// System.out.println(NumberTools.longToString(1000));// System.out.println(NumberTools.stringToLong("000000000000rs"));//// System.out.println(DateTools.dateToString(new Date(), Resolution.DAY));// System.out.println(DateTools.dateToString(new Date(), Resolution.MINUTE));// System.out.println(DateTools.dateToString(new Date(), Resolution.SECOND));// }/** * 通配符查询 *  * '?' 代表一个字符, '*' 代表0个或多个字符 *  * name:房* *  * name:*o* *  * name:roo? */@Testpublic void testWildcardQuery() {Term term = new Term("name", "roo?");// Term term = new Term("name", "ro*"); // 前缀查询 PrefixQuery// Term term = new Term("name", "*o*");// Term term = new Term("name", "房*");Query query = new WildcardQuery(term);queryAndPrintResult(query);}/** * 短语查询 *  * content:"? 绅士 ? ? 饭店" *  * content:"绅士 饭店"~2 */@Testpublic void testPhraseQuery() {PhraseQuery phraseQuery = new PhraseQuery();//表示饭店和绅士中间个两个词语隔(2,3),这个位置是相对的,只要中间隔两个即可// phraseQuery.add(new Term("content", "绅士"), 1);// phraseQuery.add(new Term("content", "饭店"), 4);//现在我不知道查多少个,但是我知道大约查几个phraseQuery.add(new Term("content", "绅士"));//第三个属性位置不填 ->phraseQuery.add(new Term("content", "饭店"));//->默认是012345递增//这个表示上面两个词最多中间隔了几个词phraseQuery.setSlop(2);queryAndPrintResult(phraseQuery);}/** * +content:"绅士 饭店"~2 -size:[000000000000dw TO 000000000000rs] *  * +content:"绅士 饭店"~2 +size:[000000000000dw TO 000000000000rs] *  * content:"绅士 饭店"~2 size:[000000000000dw TO 000000000000rs] *  * +content:"绅士 饭店"~2 size:[000000000000dw TO 000000000000rs] */@Testpublic void testBooleanQuery() {// 条件1PhraseQuery query1 = new PhraseQuery();query1.add(new Term("content", "绅士"));query1.add(new Term("content", "饭店"));query1.setSlop(2);// 条件2Term lowerTerm = new Term("size", NumberTools.longToString(500));Term upperTerm = new Term("size", NumberTools.longToString(1000));Query query2 = new RangeQuery(lowerTerm, upperTerm, true);// 组合BooleanQuery boolQuery = new BooleanQuery();boolQuery.add(query1, Occur.MUST);boolQuery.add(query2, Occur.SHOULD);queryAndPrintResult(boolQuery);}/** * 有+-的方式 +表示MUST -表示MUST_NOT  什么都不写表示SHOULD * 也有AND OR NOT的方式 */@Testpublic void testQueryString() {// String queryString = "+content:\"绅士 饭店\"~2 -size:[000000000000dw TO 000000000000rs]";// String queryString = "content:\"绅士 饭店\"~2 AND size:[000000000000dw TO 000000000000rs]";// String queryString = "content:\"绅士 饭店\"~2 OR size:[000000000000dw TO 000000000000rs]";// String queryString = "(content:\"绅士 饭店\"~2 NOT size:[000000000000dw TO 000000000000rs])";//String queryString = "-content:\"绅士 饭店\"~2 AND -size:[000000000000dw TO 000000000000rs]";//String queryString = "-content:\"绅士 饭店\"~2 OR -size:[000000000000dw TO 000000000000rs]";String queryString = "-content:\"绅士 饭店\"~2 NOT -size:[000000000000dw TO 000000000000rs]";QueryResult qr = indexDao.search(queryString, 0, 10);System.out.println("总共有【" + qr.getRecordCount() + "】条匹配结果");for (Document doc : qr.getRecordList()) {File2DocumentUtils.printDocument(doc);}}}

7、lucene的工具方法

package cn.hj.lucene.utils;import java.io.File;import java.io.IOException;import org.apache.commons.io.FileUtils;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.document.NumberTools;import org.apache.lucene.document.Field.Index;import org.apache.lucene.document.Field.Store;public class File2DocumentUtils {/** * 把文件内容转化为Document * @param path * @return */public static Document file2Document(String path){File file = new File(path);Document doc = new Document();doc.add(new Field("name",file.getName(),Store.YES,Index.ANALYZED));try {doc.add(new Field("content",FileUtils.readFileToString(file),Store.YES,Index.ANALYZED));} catch (IOException e) {e.printStackTrace();}doc.add(new Field("size",String.valueOf(path.length()),Store.YES,Index.NOT_ANALYZED));doc.add(new Field("path",path,Store.YES,Index.NO));return doc;}/** * 打印搜索结果信息 */public static void printDocument(Document doc){//第一种方式的获取值//Field field = doc.getField("name");//String name = field.stringValue();//第二种方式的获取值System.out.println("----------------------------------");System.out.println("name    = "+doc.get("name"));System.out.println("content = "+doc.get("content"));//System.out.println("size    = "+doc.get("size"));System.out.println("size    = "+NumberTools.stringToLong(doc.get("size")));System.out.println("path    = "+doc.get("path"));}}

工程代码:http://download.csdn.net/detail/wxwzy738/5248905


原创粉丝点击