`
北风norther
  • 浏览: 13417 次
  • 性别: Icon_minigender_1
  • 来自: 邯郸
社区版块
存档分类
最新评论
阅读更多

lucene。。数据从数据库中获得,

所以我下面展示的代码描述的就是一个,

    1,从数据库查数据,然后把这些数据通过lucene创建索引库保存在硬盘上。

    2,从索引库查出数据。

    3,完!

package com.bjtc;

import java.io.File;     
import java.io.Reader;
import java.io.StringReader;
import java.sql.Connection;     
import java.sql.ResultSet;     
import java.sql.Statement;     
import java.util.regex.Pattern;


import org.apache.lucene.analysis.Analyzer;     
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Analyzer.TokenStreamComponents;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.analysis.pattern.PatternTokenizer;
import org.apache.lucene.document.Document;     
import org.apache.lucene.document.Field;     
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.FieldType.NumericType;
import org.apache.lucene.document.FloatField;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.PatternAnalyzer;

public class CreateIndex {
	static String indexpath="e:\\indextest\\index";
	static File indexFile = null; 
    Analyzer analyzer = null;  
    String brandsql="(select b.name from brand b where b.id=g.brand_id) as brandName";
    String categorySql="(select c.name from category c where c.id=g.category_id) as categroyName";
    String price ="(select max(s.price) from seller_goods s where s.goods_id=g.id) as Sprice";
    String attrSql="select * from Goods_Attr where goods_id=";
    String sql="select g.* ,"+brandsql+","+categorySql+","+price+" from goods g";
	
	public void create() throws Exception{
		//连接数据库,获得数据源
		Connection conn =DButil.getConnection();
		if(conn == null) {     
            throw new Exception("数据库连接失败");     
        }
		Statement stmt=conn.createStatement();
		ResultSet rs=stmt.executeQuery(sql);
		
		//控制创建索引,与之对应的有IndexReader来读取索引
		IndexWriter indexWriter = null;
		
		 indexFile = new File(indexpath);//创建文件夹
		 if(!indexFile.exists()) {     
            indexFile.mkdir();     
        } 
		 
		 //打开存放索引的路径
		 Directory directory = FSDirectory.open(indexFile); 
		 
		 //中文标准分词器
		 Analyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_4_9);
		 //Analyzer analyzer2= new IK_CAnalyzer();
		 IndexWriterConfig inWC=new IndexWriterConfig(Version.LUCENE_4_9, analyzer);//IndexWriterConfig
		 inWC.setOpenMode(OpenMode.CREATE);//每次生成索引时把原有索引删除,生存新的索引
		 indexWriter = new IndexWriter(directory,inWC);     
		 
		 Document doc = null;  
		 int x=0;//查看最后一共搜出多少条数据
		 System.out.println("正在创建索引ing.....");
        while(rs.next()) {     
            doc = new Document(); 
            //因为是最新版本的lucene,所以网上很多的方法不能直接使用
            //使用lucene版本是4_9的,下面的方法已经过时不用
            //Field id = new Field("id", String.valueOf(rs.getInt("id")),Field.Store.YES, Field.Index.NOT_ANALYZED);
           
            FieldType fstr=new FieldType();//定义field字段的属性
            fstr.setIndexed(true);//索引
            fstr.setStored(true);//存储
            
            //下面用的StringField,默认是不分词的!
            doc.add(new StringField("brand",rs.getString("brandName"),Field.Store.YES));
            doc.add(new StringField("category",rs.getString("categroyName"),Field.Store.YES));
            doc.add(new StringField("brief",rs.getString("brief")==null?" ":rs.getString("brief"),Field.Store.YES));
            doc.add(new StringField("type_no", rs.getString("type_no"), Field.Store.YES));
            //下面用到了FieldType使其分词并被索引。不推荐这样用
            //建议使用TextField("name", rs.getString("name"),Store.YES);
            doc.add(new Field("name", rs.getString("name"),fstr));   
            doc.add(new StringField("code",rs.getString("code"),Field.Store.YES));
            //document中可以存空串,但放null
            doc.add(new StringField("image",rs.getString("image")==null?"":rs.getString("image"),Store.YES));
            
           /* FieldType fInt=new FieldType();配置数字类型,
            fInt.setNumericType(NumericType.INT);
            fInt.setIndexed(false);不索引
            fInt.setStored(true);
            FieldType fFloat=new FieldType();
            fFloat.setNumericType(NumericType.FLOAT);
            fFloat.setIndexed(true);
            fFloat.setStored(true);*/
            doc.add(new IntField("id",rs.getInt("id"),Store.YES));
            doc.add(new FloatField("price", rs.getFloat("Sprice"),Store.YES));
            doc.add(new IntField("click_count",rs.getInt("click_count"),Store.YES));
            doc.add(new IntField("attention",rs.getInt("attention"),Store.YES));
            String strs="";
            String sqll=attrSql+rs.getInt("id");
            Statement stmt2=conn.createStatement();
    		ResultSet rs2=stmt2.executeQuery(sqll);
    		while(rs2.next()){
    			strs=rs2.getString("attr_value")+","+strs;
    		}
    		/*PatternAnalyzer pa=new PatternAnalyzer(",");此处使用的是自定义分词器,可以在doc里存TokenStream,但不可以存储
    		TokenStream ts= analyzer.tokenStream("GoodsAttr", new StringReader(strs));*/
    		rs2.close();
    		doc.add(new Field("GoodsAttr",strs,fstr));
            indexWriter.addDocument(doc);
            x++;
        }
        System.out.println("数据库查询结果   :"+x);
        System.out.println("索引创建完成!");
        indexWriter.close();  
        directory.close();
	}
	public static void main(String[] args) throws Exception{
		new CreateIndex().create();
	}
}

 建立好索引库后就开始搜索吧

package com.bjtc;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
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.queryparser.classic.QueryParser.Operator;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import TEST.MyAnalyzer;


public class search {
	String indexPath = "e:\\indextest\\index";
	private Integer currentPage;
	private Integer MaxPage;
	private List<Goods> list;
	
	public Integer getMaxPage() {
		return MaxPage;
	}

	public List<Goods> getList() {
		return list;
	}

	public Integer getCurrentPage() {
		return currentPage;
	}
	/**@NortherSong
	 * 多个条件精确搜索,下面有类似淘宝京东大搜索框搜索
	 * 实现了分页功能
	 * @param brand	搜索条件
	 * @param category 	搜索条件
	 * @param price	搜索条件
	 * @param attr	搜索条件
	 * @param pagerSize	一页中含数据
	 * @param currentPage	页码
	 * @throws IOException
	 * @throws ParseException
	 */
	
	public search(String brand,String category,String price,String attr,int pagerSize,int currentPage) throws IOException, ParseException{
		System.out.println("搜索条件:");
		System.out.println("category ------"+category);
		System.out.println("brand    ------"+brand);
		System.out.println("attr     ------"+attr);
		
		BooleanQuery bq=new BooleanQuery();//多个搜索条件的Query
		
		//Term是最小的搜索单元
		TermQuery termQuery1 = new TermQuery(new Term("brand", brand));
		TermQuery termQuery2 = new TermQuery(new Term("category", category));
		
		if(price.length()>0){
			String[] ps=price.split("-");
			//NumericRangeQuery.newFloatRange范围搜索
			Query q= NumericRangeQuery.newFloatRange("price", Float.valueOf(ps[0]), Float.valueOf(ps[1]), true, true);
			bq.add(q, Occur.MUST);
		}
		//Occur.MUST表示BooleanQuery中条件为并的关系,SHORLD:或
		if(null!=brand&&brand.trim().length()!=0)
			bq.add(termQuery1, Occur.MUST);
		if(null!=category&&category.trim().length()!=0)
			bq.add(termQuery2, Occur.MUST);
		if(null!=attr&&attr.trim().length()!=0)
		{
			String[] attrs = attr.split(" ");
			for(String atr:attrs){
				if(atr.length()>1){
					atr= atr.trim();
					System.out.println(attr);
					bq.add(new TermQuery(new Term("goodsAttr", atr)), Occur.MUST);
					//bq.add(q, Occur.MUST);
				}
			}
		}
		
		//同创建索引时一样,要打开存放索引的路径
		Directory d = FSDirectory.open(new File(indexPath));
		IndexReader reader = DirectoryReader.open(d);//流读取
		//对所搜索出的数据进行排序
		Sort sort= new Sort();
		//默认为false 升序
		SortField s= new SortField("price", SortField.Type.FLOAT);
		sort.setSort(s);
		
		IndexSearcher searcher = new IndexSearcher(reader);//搜索  
		//searcher.search(QUERY,FILTER过滤器,最多获取数据DOCUMENT条数,sort排序);
		TopDocs topDocs = searcher.search(bq, null, 10000,sort);
		System.out.println("符合条件的" + topDocs.totalHits + "---");
		//分页
		int begin=pagerSize*(currentPage-1);
		int end=Math.min(topDocs.scoreDocs.length, begin+pagerSize);
		
		List<Goods> list = new ArrayList<Goods>();
		Goods g = null;
		for(int i=begin;i<end;i++){
			int docSn = topDocs.scoreDocs[i].doc;
			Document doc = reader.document(docSn);
			g = new Goods();
			g.setId(Integer.parseInt(doc.get("id")));
			g.setName(doc.get("name"));
			g.setCode(doc.get("code"));
			g.setBrandName(doc.get("brand"));
			g.setCategoryName(doc.get("category"));
			g.setPrice(Float.valueOf(doc.get("price")));
			g.setS(doc.get("goodsAttr"));//z注意大小写
			list.add(g);
		}
		//用完记得关闭流~
		reader.close();
		d.close();
		this.MaxPage=topDocs.totalHits;
		this.currentPage=currentPage;
		this.list= list;
	}
	
	public  search(String queryStr,int pagerSize,int currentPage) throws IOException, ParseException {
		
	//	QueryParser qp = new QueryParser(Version.LUCENE_4_9, "goodsAttr",
	//			new PatternAnalyzer(" "));对单一的字段进行搜索 例如条件可以是“联想   G”这样,我可能搜出手机或者电脑
		MultiFieldQueryParser mp = new MultiFieldQueryParser(//搜索多个字段 例如“联想  电脑  红色”
				Version.LUCENE_4_9, new String[] {"name","brandName","categoryName"},
				new SmartChineseAnalyzer(Version.LUCENE_4_9));
		mp.setDefaultOperator(Operator.AND);//多个字段之间的关系是或还是并专业点是  &&还是||
		
		Query query= mp.parse(queryStr);
		
		Directory d = FSDirectory.open(new File(indexPath));
		IndexReader reader = DirectoryReader.open(d);
		
		Sort s= new Sort();
		//默认为false 升序
		SortField sf= new SortField("price", SortField.Type.FLOAT);
		s.setSort(sf);
		IndexSearcher searcher = new IndexSearcher(reader);

		TopDocs topDocs = searcher.search(query, null, 10000,s);
		System.out.println("符合条件的" + topDocs.totalHits + "---");
		int begin=pagerSize*(currentPage-1);
		int end=Math.min(topDocs.scoreDocs.length, begin+pagerSize);
		
		List<Goods> list = new ArrayList<Goods>();
		Goods g = null;
		for(int i=begin;i<end;i++){
			int docSn = topDocs.scoreDocs[i].doc;
			Document doc = reader.document(docSn);
			g = new Goods();
			g.setId(Integer.parseInt(doc.get("id")));
			g.setName(doc.get("name"));
			g.setCode(doc.get("code"));
			g.setBrandName(doc.get("brand"));
			g.setCategoryName(doc.get("category"));
			g.setPrice(Float.valueOf(doc.get("price")));
			g.setS(doc.get("goodsAttr"));
			list.add(g);
		}
		
		reader.close();
		d.close();
		this.MaxPage=topDocs.totalHits;
		this.currentPage=currentPage;
		this.list= list;
	}
	
	public static void main(String[] args) throws IOException, ParseException{
		search ss= new search("8.5Kg 2500W tcl", 13,1);
		for(Goods g:ss.getList()){
			System.out.println("name           "+g.getName());
			System.out.println("attr           "+g.getS());
			
		}
	}
	
}

 

分享到:
评论

相关推荐

    Lucene_in_Action(中文版).pdf

    Lucene_in_Action(中文版)....1. 接触 Lucene 2. 索引 3. 为程序添加搜索 4. 分析 5. 高极搜索技术 6. 扩展搜索 第二部分 Lucene 应用 7. 分析常用文档格式 8. 工具和扩充 9. Lucene 其它版本 10. 案例学习

    lucene 小资源

    lucene 小资源,只是接触lucene的经验积累过程,从中学习一些有意义的经验。

    lucene搜索引擎

    本课件用于刚开始学习和接触lucene的人员,仅供参考。

    lucenedome

    亲密接触lucene,被它的强大简单所折服,俺用lucene+paoding做了一个demo。可以对测试文本索引,对文件索引,对数据库索引,详情请查看压缩包中ReadMe.txt文件

    lucene4.4 Demo事例

    lucene4.,4事例,包含lucene4.4的增删改查,分页查询,适合更开始接触搜索引擎的朋友参考,下载了包你不后悔,因为我也是初学者,根据一些资源学习后,自己写的,适合大家参考

    Lucene初级教程.doc

    Lucene初级教程 没接触过Lucene可以学习!

    lucene 搜索引擎小例子

    如果你没接触过 lucene 搜索引擎,如果你不知道搜索引擎的简单原理,你可以看看,保证你看后能对搜索引擎有个深刻的印象。

    lucene之第一次亲密接触

    NULL 博文链接:https://inter12.iteye.com/blog/1307501

    Lucene-MoreLikeThis-example:使用 Java 和 Lucene 4.2 的 MoreLikeThis 代码示例

    Lucene MoreLikeThis 示例 - 搜索相似文档使用 Java 和 Lucene 4.2 的 MoreLikeThis 代码示例安装假设你已经安装了 Maven。 您可以运行以下命令: mvn ...接触由 Martin Magakian 开发执照麻省理工学院执照 (MIT) 通过

    lucene入门知识

    lucne的一些简单介绍、希望对刚接触的人有所帮助

    lucene-solr-operator:Apache Solr的Kubernetes运算符

    如果您在使用Solr运算符时遇到问题,请: 请参考下面提供的在此仓库中创建一个Github Issue,尽可能详细地描述您的问题接触我们的Slack频道! 在Kubernetes官方松弛工作区的频道上加入我们。菜单文献资料请访问以下...

    TestRecorder For WatiN 优化重构版

    做为一名IT人,接触NET有几年了,随着对NET的逐渐了解,看到一个很有意思的现象,就是好多平台的框架,组件很容易移植到NET平台,如Junit, Lucene,Ant,WatiR,Hibernate,Log4等等,但好多后来就沉了如NetBPM,BugNet,...

    Liferay入门帮助文档(Liferay开发指南)

    基于J2EE的应用,使用了EJB以及JMS等技术,前台界面部分使用Struts MVC 框架,基于XML的portlet配置文件可以自由地动态扩展,使用了Web服务来支持一些远程信息的获取,使用 Lucene实现全文检索功能。 Liferay国内用...

    全文检索Solr8.0-架构师速成记

    毕业后接触的第一个中间件就是Solr,在工作中用处广泛,为了便于大家快速掌握该技能,开始录制相关课程,该专栏特点如下: 1.采用Solr最新版本视频录制,全网最新课程(Solr8.1于2019年5月16日发布) 2.技能点全网最...

    航空订票系统java源码-resume:NikhilPrabhakar的简历作为Git时间线

    接触 电子邮件: 概括 我目前在 LinkedIn (SlideShare) 担任高级软件工程师。 当前/以前的工作总结: 在 Cleartrip Travels [],我是开发航班/酒店搜索/预订系统的后端团队的一员。 我在飞行队。 我和我的导师一起...

    大数据培训课程安排.pdf

    本阶段将第⼀次 接触团队开发、产出具有前后台(第⼀阶段技术+第⼆阶段的技术综合应⽤)的真实项⽬。 第三阶段:前端框架 1. 难易程序:两星 2. 课时量(技术知识点+阶段项⽬任务+综合能⼒):64课时 3. 主要技术...

    全文搜索引擎 ElasticSearch 还是 Solr?

    图片来自Pexels 最近项目组安排了一个...但是先不考虑本身设计的合理性,领导需要开发,所以我开始踏上了搭建 ES 服务的道路,从零开始,因为之前完全没接触过 ES,所以通过本系列来记录下自己的开发过程。 什么是全

Global site tag (gtag.js) - Google Analytics