lucene oschina 搜索框架使用

panmingguang 发布于 2014/11/28 16:42
阅读 578
收藏 20

很久就见到 oschina 的开源的 搜索框架, 一直没有使用 最近实际使用了一把

没想到 意外的 简单, 使用也非常 方便, 索引设计方面参考 下面的链接

http://www.oschina.net/question/12_71591

主要设计的 类有三个

IndexHolder  SearchHelper Searchable

IndexHolder 包括所有的 索引操作方法

SearchHelper 里面一些辅助 方法,主要 三个 makeQuery objtodoc doctoobj highlight 主要这几个比较常用

Searchable 是一个接口, 主要用于 定义了 需要存储, 需要索引, 和 最后 扩展的 索引数据等

在初期的时候使用的 时候看到 一个问题:  在oschina 也有人提问过, 解决方案也有

就是 doctoobj的 时候 里面除了 id 以外 其他的属性 没有 赋值,

具体代码:


/**
     * 获取文档对应的对象类
     * @param doc
     * @return
     * @throws ClassNotFoundException 
     */
	public static Searchable doc2obj(Document doc) {
    	try{
    		String id = docid(doc);
    		if(id == null)
    			return null;
    		Searchable obj = (Searchable)Class.forName(doc.get(FN_CLASSNAME)).newInstance();
    		obj.setId(id);
    		 /************增加****************/
            //属性设置
            List<String> fields = obj.storeFields();
            for(String field : fields) {
                PropertyUtils.setProperty(obj, field, doc.get(field));
            }
            /*******************************/
    		return obj;
    	}catch(Exception e){
    		log.error("Unabled generate object from document#id="+doc.toString(), e);
    		return null;
    	}
    }



加上注释增加的那段代码就可以了, 不过后来想想, 其实加了也没用, 因为 @红薯 在做textField 索引的时候都是做 NO 存储 数据的, 所以总是获取不到的


继续向下使用, 我用, 我用, 索引加上了, 可以搜索到了, 到了高亮的问题, 其实在 使用 oschina 的时候 也总是出现 这个问题, 总是 搜索到了数据 却没有 显示 高亮出来

后来查找代码 


/**
     * 对一段文本执行语法高亮处理
     * @param text 要处理高亮的文本
     * @param key 高亮的关键字
     * @return 返回格式化后的HTML文本
     */
    public static String highlight(String text, String key) {
        if(StringUtils.isBlank(key) || StringUtils.isBlank(text))
            return text;
        String result = null;
        try {
//        	PhraseQuery pquery = new PhraseQuery();
//        	for(String sk : splitKeywords(key)){
//        		pquery.add(new Term("",QueryParser.escape(sk)));
//        	}         
            QueryScorer scorer = new QueryScorer(makeQuery("content", key, 1.0F));
            Highlighter hig = new Highlighter(highlighter_formatter, scorer);
            TokenStream tokens = analyzer.tokenStream(null, new StringReader(text));
            result = hig.getBestFragment(tokens, text);
        } catch (Exception e) {
            log.error("Unabled to hightlight text", e);
        }
        return (result != null)?result:text;
    }



其中 用了 PhraseQuery 这个query 对象, 并使用了手动 分词 加入 term, 后来发现这个类 只能 一个item 生效, 多个 都没有生效, 导致了高亮没有效果, 后来我改为后来 本来他 有的 makeQuery, 这个是分词query, 会自动分词, 使用了IK分词, 改过后 的确 解决了这个问题, 不过makeQuery 有个 key的字段参数, 如果不定的话 就没法搜索到, 以前用PhraseQuery key 给的"" , 没有指定.

到此为止, 基本作为生产环境 没有大的问题, 后来 又发现了一个问题, 这个可能是lecene 没有用好

至此我也没有 去深入研究, 就是 搜索 几个词的, 只有一段文字中 都包涵 这几个词 才会搜索出来, 并没有 说是 只要带了 其中一个 分词 就 搜索到

至此, lucene 算入门使用, 还是要感谢 @红薯 的分享, 两年前就有了这段 代码, 两年后才 真正的 使用到

加载中
0
slliver
slliver

对于楼主的说法我有一点疑问

红薯在做字段存数的时候

 //存储字段
 List<String> fields = obj.storeFields();

在真正pojo的时候已经

/**
     * 要存储的字段
     * @return 返回字段名列表
     */
    @Override
    public List<String> storeFields(){
        return Arrays.asList("title");
    }

所以在从doc->pojo的时候那个地方是有值的 我已经验证了



0
slliver
slliver
还有一个疑问,按照红薯的写法,只是从doc里获取了一些Id 红薯是不是很据ID从缓存获取这些ID对应的数据信息了,不会在此查询数据库了吧,刚接触这个东西,说错了请勿见笑 
panmingguang
panmingguang
的确是 只写了id 而已, 这个 @红薯 多次提到过, 具体 更具id 取数据 是从直接从数据库取 还是从其他缓存中取 就不吃很清楚了
0
slliver
slliver
恩恩,lucene不错,现在在使用
返回顶部
顶部