8、搜索排序和搜索过滤(lucene笔记)

一、搜索排序(工程lucene_analyzer03

这里我们使用之前工程中创建索引的一个工具类```FileIndexUtil.java

package cn.itcast.util;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;

public class FileIndexUtil {

    private static Directory directory = null;
    static {
        try {
            directory = FSDirectory.open(new File(
                    "E:/myeclipse/Lucene/index"));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Directory getDirectory() {
        return directory;
    }

    // 创建索引
    public static void index(boolean hasNew) {
        IndexWriter writer = null;
        try {
            writer = new IndexWriter(directory, new IndexWriterConfig(
                    Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
            if (hasNew) {
                writer.deleteAll();//如果我们要新建索引,那么将之前创建的删除
            }
            File file = new File("E:/myeclipse/Lucene/somefile");

            Document document = null;
            for (File f : file.listFiles()) {
                document = new Document();
                document.add(new Field("content", new FileReader(f)));
                document.add(new Field("filename", f.getName(),
                        Field.Store.YES, Field.Index.NOT_ANALYZED));
                document.add(new Field("path", f.getAbsolutePath(),
                        Field.Store.YES, Field.Index.NOT_ANALYZED));
                document.add(new NumericField("date", Field.Store.YES, true)
                        .setLongValue(f.lastModified()));
                // 最后我们将字节数转换成kb
                document.add(new NumericField("size", Field.Store.YES, true)
                        .setIntValue((int) (f.length())));
                writer.addDocument(document);
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (LockObtainFailedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (CorruptIndexException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

说明:此类是之前我们写的一个创建索引的类。下面再写一个类用于测试排序的类SearchTest.java

package cn.lucene.test;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.util.Version;
import cn.itcast.util.FileIndexUtil;

public class SearchTest {

    private static IndexReader reader;
    static {
        try {
            reader = IndexReader.open(FileIndexUtil.getDirectory());
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public IndexSearcher getSearcher() {
        try {
            if (reader == null) {
                reader = IndexReader.open(FileIndexUtil.getDirectory());
            } else {
                IndexReader tr = IndexReader.openIfChanged(reader);
                if (tr != null) {
                    reader.close();
                    reader = tr;
                }
            }
            return new IndexSearcher(reader);
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void searcher(String queryStr, Sort sort) {
        try {
            IndexSearcher searcher = getSearcher();
            QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
                    new StandardAnalyzer(Version.LUCENE_35));
            Query query = parser.parse(queryStr);
            TopDocs tds = null;
            if (sort != null) {
                tds = searcher.search(query, 50, sort);
            } else {
                tds = searcher.search(query, 50);
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (ScoreDoc sd : tds.scoreDocs) {
                Document doc = searcher.doc(sd.doc);
                System.out.println("id:" + sd.doc + ",评分:" + sd.score + ",名称:"
                        + doc.get("filename") + ",路径:" + doc.get("path")
                        + ",文件大小:" + doc.get("size") + ",日期:"
                        + sdf.format(new Date(Long.valueOf(doc.get("date")))));
            }
            searcher.close();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

相关的代码我们在之前已经讲过,下面我们进行排序测试TestAnalyzer.java

package cn.lucene.test;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.junit.Before;
import org.junit.Test;
import cn.itcast.util.FileIndexUtil;

public class TestAnalyzer {
    private SearchTest st;
    
    @Before
    public void init(){
        st = new SearchTest();
    }
    
    //重新创建索引
    @Test
    public void Index(){
        FileIndexUtil.index(true);
    }
    
    @Test
    public void test01(){
        //只要设置了排序,那么评分就没有了
        //st.searcher("java", Sort.INDEXORDER);//以序号排序
        //st.searcher("java", Sort.RELEVANCE);//通过评分排序
        
        //st.searcher("java", new Sort(new SortField("size", SortField.INT)));//通过文件大小排序
        //st.searcher("java", new Sort(new SortField("date", SortField.LONG)));//通过日期排序
        //st.searcher("java", new Sort(new SortField("filename", SortField.STRING)));//通过文件名排序,升序
        //st.searcher("java", new Sort(new SortField("filename", SortField.STRING, true)));//通过文件名排序,降序
        //先按大小排序,再按评分排序
        st.searcher("java", new Sort(new SortField("size", SortField.INT), SortField.FIELD_SCORE));
    }
}

说明:通过上面的测试代码我们可以看到,lucene默认有很多排序的规则,只要我们自行设置好便可达到相关排序的目的,当然在后面我们还需要自定义排序规则来达到我们的要求,这里只是入门。

二、搜索过滤

这里我们说三个进行搜索过滤的过滤器,其实前面已经提到,这里作为复习.
SearchTest.java

    public void searcher(String queryStr, Filter filter){
        try {
            IndexSearcher searcher = getSearcher();
            QueryParser parser = new QueryParser(Version.LUCENE_35, "content",
                    new StandardAnalyzer(Version.LUCENE_35));
            Query query = parser.parse(queryStr);
            TopDocs tds = null;
            if (filter != null) {
                //这里我们使用过滤器
                tds = searcher.search(query, filter, 50);
            } else {
                tds = searcher.search(query, 50);
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (ScoreDoc sd : tds.scoreDocs) {
                Document doc = searcher.doc(sd.doc);
                System.out.println("id:" + sd.doc + ",评分:" + sd.score + ",名称:"
                        + doc.get("filename") + ",路径:" + doc.get("path")
                        + ",文件大小:" + doc.get("size") + ",日期:"
                        + sdf.format(new Date(Long.valueOf(doc.get("date")))));
            }
            searcher.close();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

说明:在这个方法中我们传入的不是排序类,而是过滤器。下面进行测试。

    @Test
    public void test02(){
        //范围搜索,从json.c到json.php的分为内搜索json,最后两个参数表示是前后都是闭区间
        Filter tr = new TermRangeFilter("filename", "json.c", "json.php", true, true);
        //大小范围搜索
        tr = NumericRangeFilter.newIntRange("size", 10, 100, true, true);
        //可以通过一个query进行过滤
        tr = new QueryWrapperFilter(new WildcardQuery(new Term("filename", "*.c")));
        st.searcher("json", tr);
    }

说明:这里我们给出了三个过滤器,分别进行名字范围、发笑范围过滤器和一个可以通过Query进行过滤去过滤器。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,361评论 25 707
  • 按道理这是2月12日的日记,今天才来写完它。 今天从乡下接我外甥回市区,他在车上问我“阿姨,你好朋友有多少个?”,...
    跳跃时光的周小周阅读 406评论 0 9
  • 做事要循序渐进才是王道,细水长流才是最好呢,饭要一口一口吃。 睡饱了才能有精力坚持。每天有进步 才是真的。 加油。
    刘韧阅读 161评论 0 0
  • 4.21日一季度分析会 这是我四月份从导图学院回来第一次用于自己的工作实践,因为有之前15副的经验,那么首次的会...
    章鱼妈妈Mindmap阅读 88评论 0 0