lucene的多种搜索2-SpanQuery
SpanQuery按照词在文章中的距离或者查询几个相邻词的查询
SpanQuery包括以下几种:
SpanTermQuery:词距查询的基础,结果和TermQuery相似,只不过是增加了查询结果中单词的距离信息。
SpanFirstQuery:在指定距离可以找到第一个单词的查询。
SpanNearQuery:查询的几个语句之间保持者一定的距离。
SpanOrQuery:同时查询几个词句查询。
SpanNotQuery:从一个词距查询结果中,去除一个词距查询。
下面一个简单例子介绍
- package com;
- //SpanQuery:跨度查询。此类为抽象类。
- import java.io.IOException;
- import java.io.StringReader;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.lucene.analysis.Analyzer;
- import org.apache.lucene.analysis.Token;
- import org.apache.lucene.analysis.TokenStream;
- import org.apache.lucene.analysis.WhitespaceAnalyzer;
- import org.apache.lucene.document.Document;
- import org.apache.lucene.document.Field;
- import org.apache.lucene.document.Field.Index;
- import org.apache.lucene.document.Field.Store;
- import org.apache.lucene.index.IndexReader;
- import org.apache.lucene.index.IndexWriter;
- import org.apache.lucene.index.Term;
- import org.apache.lucene.search.Hits;
- import org.apache.lucene.search.IndexSearcher;
- import org.apache.lucene.search.spans.SpanFirstQuery;
- import org.apache.lucene.search.spans.SpanNearQuery;
- import org.apache.lucene.search.spans.SpanNotQuery;
- import org.apache.lucene.search.spans.SpanOrQuery;
- import org.apache.lucene.search.spans.SpanQuery;
- import org.apache.lucene.search.spans.SpanTermQuery;
- import org.apache.lucene.search.spans.Spans;
- import org.apache.lucene.store.RAMDirectory;
- public class SpanQueryTest {
- private RAMDirectory directory;
- private IndexSearcher indexSearcher;
- private IndexReader reader;
- private SpanTermQuery quick;
- private SpanTermQuery brown;
- private SpanTermQuery red;
- private SpanTermQuery fox;
- private SpanTermQuery lazy;
- private SpanTermQuery sleepy;
- private SpanTermQuery dog;
- private SpanTermQuery cat;
- private Analyzer analyzer;
- // 索引及初使化
- public void index() throws IOException {
- directory = new RAMDirectory();
- analyzer = new WhitespaceAnalyzer();
- IndexWriter writer = new IndexWriter(directory, analyzer, true);
- Document doc1 = new Document();
- doc1.add(new Field("field",
- "the quick brown fox jumps over the lazy dog", Store.YES,
- Index.TOKENIZED));
- Document doc2 = new Document();
- doc2.add(new Field("field",
- "the quick red fox jumps over the sleepy cat", Store.YES,
- Index.TOKENIZED));
- writer.addDocument(doc1);
- writer.addDocument(doc2);
- writer.optimize();
- writer.close();
- quick = new SpanTermQuery(new Term("field", "quick"));
- brown = new SpanTermQuery(new Term("field", "brown"));
- red = new SpanTermQuery(new Term("field", "red"));
- fox = new SpanTermQuery(new Term("field", "fox"));
- lazy = new SpanTermQuery(new Term("field", "lazy"));
- sleepy = new SpanTermQuery(new Term("field", "sleepy"));
- dog = new SpanTermQuery(new Term("field", "dog"));
- cat = new SpanTermQuery(new Term("field", "cat"));
- indexSearcher = new IndexSearcher(directory);
- reader = IndexReader.open(directory);
- }
- private void dumpSpans(SpanQuery query) throws IOException {
- // 检索效果和TermQuery一样,可以把他当成TermQuery
- Hits hits = indexSearcher.search(query);
- for (int i = ; i < hits.length(); i++) {
- // System.out.println(hits.doc(i).get("field"));
- }
- // 但内部会记录一些位置信息,供SpanQuery的其它API使用,是其它属于SpanQuery的Query的基础。
- Spans spans = query.getSpans(reader);
- int numSpans = ;
- float[] scores = new float[];
- for (int i = ; i < hits.length(); i++) {
- scores[hits.id(i)] = hits.score(i);
- }
- while (spans.next()) {
- numSpans++;
- int id = spans.doc();
- Document doc = reader.document(id);
- Token[] tokens = AnalyzerUtils.tokensFromAnalysis(analyzer, doc
- .get("field"));
- StringBuffer buffer = new StringBuffer();
- for (int i = ; i < tokens.length; i++) {
- // the quick brown fox jumps over the lazy dog
- // spans记录了位置信息,比如搜索brown,brown在这句话中位于第三个位置,所以spans.start()=2,spans.end()=3
- // 在第二项的位置后加<,第三项后加> 返回<brown>
- if (i == spans.start()) {
- buffer.append("<");
- }
- buffer.append(tokens[i].termText());
- if (i + == spans.end()) {
- buffer.append(">");
- }
- buffer.append(" ");
- }
- buffer.append("(" + scores[id] + ") ");
- System.out.println(buffer);
- }
- // indexSearcher.close();
- }
- // SpanTermQuery:检索效果完全同TermQuery,但内部会记录一些位置信息,供SpanQuery的其它API使用,是其它属于SpanQuery的Query的基础。
- public void spanTermQueryTest() throws IOException {
- dumpSpans(brown);
- //// 搜索结果
- // the quick <brown> fox jumps over the lazy dog (0.22097087)
- }
- // SpanFirstQuery:查找方式为从Field的内容起始位置开始,在一个固定的宽度内查找所指定的词条。
- public void spanFirstQueryTest() throws IOException {
- // the quick brown fox jumps over the lazy dog
- // 在给定的范围搜索,前两个为the quick
- // brown 在doc1的第三个位置,用SpanFirstQuery从起点查找的话,他的跨度必须为>=3才能找到
- SpanFirstQuery firstQuery = new SpanFirstQuery(brown, );
- dumpSpans(firstQuery);
- ////搜索结果
- // the quick <brown> fox jumps over the lazy dog (0.22097087)
- }
- // SpanNearQuery:功能类似PharaseQuery。SpanNearQuery查找所匹配的不一定是短语,还有可能是另一个SpanQuery的查询结果作为整体考虑,进行嵌套查询。
- public void spanNearQueryTest() throws IOException {
- // the quick brown fox jumps over the lazy dog
- // 第二个参数为两个项的位置之间允许的最大间隔
- // 在这里两个较远的项为quick和fox,他们之是的最大间隔为5,所以slop必须>=5才能搜到结果
- SpanNearQuery nearQuery = new SpanNearQuery(new SpanQuery[] { quick,
- brown, fox }, , true);
- dumpSpans(nearQuery);
- // 与PhraseQuery短语搜索相似
- // 这里搜索quick,dog,brown,要想得到结果,就要将brown向后移动5个位置才能到dog的后面,所以slop要>=5才能找到结果
- // 第三个参数,如果为true表示保持各项位置不变,顺序搜索
- nearQuery = new SpanNearQuery(new SpanQuery[] { quick, dog, brown }, ,
- false);
- dumpSpans(nearQuery);
- //////搜索结果/////
- // 第一个dumpSpans的结果 the <quick brown fox> jumps over the lazy dog (0.34204215)
- // 第二个dumpSpans的结果 the <quick brown fox jumps over the lazy dog> (0.27026406)
- }
- // 从第一个SpanQuery查询结果中,去掉第二个SpanQuery查询结果,作为检索结果
- public void spanNotQueryTest() throws IOException {
- // the quick brown fox jumps over the lazy dog
- SpanNearQuery quick_fox = new SpanNearQuery(new SpanQuery[] { quick,
- fox }, , true);
- // 结果为quick brown fox 和 quick red fox
- dumpSpans(quick_fox);
- // SpanNotQuery quick_fox_dog = new SpanNotQuery(quick_fox, dog);
- //
- // dumpSpans(quick_fox_dog);
- // 在quick_fox结果中,去掉red,结果为quick brown fox
- SpanNotQuery no_quick_red_fox = new SpanNotQuery(quick_fox, red);
- dumpSpans(no_quick_red_fox);
- //////搜索结果///////第一个dumpSpans结果为前两条,第二个dumpSpans结果为第三条
- //the <quick brown fox> jumps over the lazy dog (0.18579213)
- //the <quick red fox> jumps over the sleepy cat (0.18579213)
- //the <quick brown fox> jumps over the lazy dog (0.18579213)
- }
- // SpanOrQuery:把所有SpanQuery查询结果综合起来,作为检索结果。
- public void spanOrQueryTest() throws IOException {
- SpanNearQuery quick_fox = new SpanNearQuery(new SpanQuery[] { quick,
- fox }, , true);
- SpanNearQuery lazy_dog = new SpanNearQuery(
- new SpanQuery[] { lazy, dog }, , true);
- SpanNearQuery sleepy_cat = new SpanNearQuery(new SpanQuery[] { sleepy,
- cat }, , true);
- SpanNearQuery qf_near_ld = new SpanNearQuery(new SpanQuery[] {
- quick_fox, lazy_dog }, , true);
- dumpSpans(qf_near_ld);
- SpanNearQuery qf_near_sc = new SpanNearQuery(new SpanQuery[] {
- quick_fox, sleepy_cat }, , true);
- dumpSpans(qf_near_sc);
- SpanOrQuery or = new SpanOrQuery(new SpanQuery[] { qf_near_ld,
- qf_near_sc });
- dumpSpans(or);
- /////////搜索结果 第一个dumpSpans结果为第一条,第二个为第二条,第三个为第三,四条
- // the <quick brown fox jumps over the lazy dog> (0.3321948)
- // the <quick red fox jumps over the sleepy cat> (0.3321948)
- // the <quick brown fox jumps over the lazy dog> (0.5405281)
- // the <quick red fox jumps over the sleepy cat> (0.5405281)
- }
- public static void main(String[] args) throws IOException {
- SpanQueryTest test = new SpanQueryTest();
- test.index();
- test.spanOrQueryTest();
- }
- }
- class AnalyzerUtils {
- public static Token[] tokensFromAnalysis(Analyzer analyzer, String text)
- throws IOException {
- TokenStream stream = analyzer.tokenStream("contents", new StringReader(
- text));
- boolean b = true;
- List<Token> list = new ArrayList<Token>();
- while (b) {
- Token token = stream.next();
- if (token == null)
- b = false;
- else
- list.add(token);
- }
- return (Token[]) list.toArray(new Token[]);
- }
- }
lucene的多种搜索2-SpanQuery的更多相关文章
- Apache Lucene(全文检索引擎)—搜索
目录 返回目录:http://www.cnblogs.com/hanyinglong/p/5464604.html 本项目Demo已上传GitHub,欢迎大家fork下载学习:https://gith ...
- Apache Solr采用Java开发、基于Lucene的全文搜索服务器
http://docs.spring.io/spring-data/solr/ 首先介绍一下solr: Apache Solr (读音: SOLer) 是一个开源.高性能.采用Java开发.基于Luc ...
- Lucene的其他搜索(三)
生成索引: package com.wp.search; import java.nio.file.Paths; import org.apache.lucene.analysis.Analyzer; ...
- 基于 Lucene 的桌面文件搜索
开源2010年,自己在学习 Lucene 时开发的一款桌面文件搜索工具,这么多年过去了,代码一直静静存放在自己的硬盘上,与其让其沉睡,不如分享出来. 这款工具带有明显的模仿 Everything 的痕 ...
- 理解Lucene索引与搜索过程中的核心类
理解索引过程中的核心类 执行简单索引的时候需要用的类有: IndexWriter.Directory.Analyzer.Document.Field 1.IndexWriter IndexWr ...
- lucene索引并搜索mysql数据库[转]
由于对lucene比较感兴趣,本人在网上找了点资料,终于成功地用lucene对mysql数据库进行索引创建并成功搜索,先总结如下: 首先介绍一个jdbc工具类,用于得到Connection对象: im ...
- Lucene多字段搜索
最近在学习Lucene的过程中遇到了需要多域搜索并排序的问题,在网上找了找,资料不是很多,现在都列出来,又需要的可以自己认真看看,都是从其他网站粘贴过来的,所以比较乱,感谢原创的作者们! 使用 ...
- WebGIS中解决使用Lucene进行兴趣点搜索排序的两种思路
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 目前跟信息采集相关的一个项目提出了这样的一个需求:中国银行等 ...
- Lucene.net 高亮显示搜索词
网站搜索关键词,往往搜索的结果中,要把用户搜索的词突出显示出来,这就是高亮搜索词的含义.而lucene也恰恰支持这样的操作.在此,我用的是盘古的组件,代码如下: PanGu.HighLight.Sim ...
随机推荐
- CodeForces 577C Vasya and Petya's Game 数学
题意就是给你一个1到n的范围 你每次可以问这个数是否可以被某一个数整除 问你要猜多少数才能确定这个数…… 一开始一点思路也没有 后来查了一下才知道 每个数都可以分为几个质数的整数次幂相乘得到…… #i ...
- UI篇—懒加载
1.懒加载基本 懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,写的是其get方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再去进行实例化 ...
- 洛谷-哥德巴赫猜想(升级版)-BOSS战-入门综合练习1
题目背景 Background 1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和.质数是指除了1和本身之外没有其他约数的数,如2和 ...
- SpringMVC利用Hibernate validator做字段验证
1.添加Hiberbate validator相关的jar包 2.字需要验证的formbean 上添加验证的注解,内置注解有: dBean Validation 中内置的 constraint @Nu ...
- Ubuntu14.04下安装redis
1.首先在官网上下载redis压缩包 redis-3.2.0.tar.gz 2.解压到到当前文件夹(这里可以解压到随意位置) tar zvxf redis-3.2.0.tar.gz 3.切换到redi ...
- Ecstore1.2启用mongodb添加索引
配置config(连接mongo) mongo define('KVSTORE_STORAGE', 'base_kvstore_mongodb'); define('MONGODB_SERVER_CO ...
- JavaScript实现本地数据简单存取以及Json数据存取
1.判断本地存储是否可用: if(window.localStorage) { // localStorge可用 }else { // localStorge不可用 } 2.存储数据: // 获取本地 ...
- javascript 深入浅出 (未完成4-17)
慕课网javascript总结 课程地址 课程大纲: 一.数据类型 二.表达式和运算符 三.语句 四.对象 五.数组 六.函数 七.this 八.闭包和作用域 九.OOP 十.正则与模式匹配 ---- ...
- leetcode383
已知两个字符串,然后比较一个字符串是否来自另一个字符串,没有顺序要求. 简单题,用一个数组保存前一个字符串的每一个字符出现的次数,然后循环后一个字符串去检查,如果次数不够了,那么就返回false pu ...
- YII2 运行概述(Overview)
运行机制概述 每一次 Yii 应用开始处理 HTTP 请求时,它都会进行一个近似的流程. 用户提交指向 入口脚本 web/index.php 的请求. 入口脚本会加载 配置数组 并创建一个 应用 实例 ...