Lucene 高阶查询的六脉神剑 —— QueryParser

Lucene(3.5)解析查询表达式:QueryParser package com.test.lucene; import java.io.File; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; imp 阅读详情

上篇我们介绍了 Lucene 多样的查询模式,每一种都是相互独立的用来解决特定查询目标的 Query 对象。本节我们要将这些查询模式使用 QueryParser 组合起来进行合并查询 —— 用一个文本字符串表达式来表示所有的查询模式。

QueryParser 的基本作用是将一个满足特定语法的字符串转换成相应的查询对象。我们可以不再需要使用组合对象的方式来手动构造复合逻辑查询,而是通过一个单行字符串就可以完成原先需要数行代码才能完成的查询功能。

关键词查询 TermQuery 与组合查询 BooleanQuery

关键词查询是最简单的查询,在 QueryParser 的语法里它就是一个「无空格」普通的字符串。

var analyser = new HanLPAnalyzer();
var parser = new QueryParser("content", analyser);
var query = parser.parse("北京大学");
System.out.println(query);
var hits = searcher.search(query, 10).scoreDocs;

--------------
content:北京大学

var query = parser.parse("北京 大学");
System.out.println(query);

------------
content:北京 content:大学

System.out.println(query.getClass());

------------
class org.apache.lucene.search.BooleanQuery

var query = parser.parse("+北京 +大学");

var query = parser.parse("+北京 -大学")

注意 QueryParser 会使用传递进去的 analyzer 对象对字符串进行分词,最开始例子的「北京大学」解析后之所以是单个字符串,那是因为「北京大学」本身就是一个完整的原子词汇。如果我们试试「北京林业大学」就会完全是不一样的结果,它是三个词汇的或运算。

var query = parser.parse("北京林业大学");

-----------------
content:北京 content:林业 content:大学

Lucence 对于整数范围和字符串范围是不一样的处理方式,它有 NumericRangeQuery 和 TermRangeQuery,但是默认的 QueryParser 表达式仅支持 TermRangeQuery,使用下面的范围表达式解析出来的结果将会是 TermRangeQuery。如果对整形的 article_id 字段进行字符串的范围查询,那么结果将会是空集。

var parser = new QueryParser("article_id", analyser);
var query = parser.parse("[400000 TO 450000]");
System.out.println(query);
System.out.println(query.getClass());

---------------
article_id:[400000 TO 450000]
class org.apache.lucene.search.TermRangeQuery

static class MyQueryParser extends QueryParser {

    public MyQueryParser(String f, Analyzer a) {
        super(f, a);
    }

    @Override
    protected Query getRangeQuery(String field, String low, String high, boolean startInclusive, boolean endInclusive) throws ParseException {
        if(this.field.equals(field)) {
            return IntPoint.newRangeQuery(field, Integer.parseInt(low), Integer.parseInt(high));
        }
        return super.getRangeQuery(field, low, high, startInclusive, endInclusive);
    }
}

var analyser = new HanLPAnalyzer();
var parser = new MyQueryParser("article_id", analyser);
var query = parser.parse("[400000 TO 450000]");
System.out.println(query);
System.out.println(query.getClass());
var hits = searcher.search(query, 10).scoreDocs;
System.out.println(hits.length);

--------------
article_id:[400000 TO 450000]
class org.apache.lucene.document.IntPoint$1
10

这两个查询都是有效利用了关键词树 FST 的前缀属性来扫描出匹配的关键词集合。PrefixQuery 可以理解为 WildcardQuery 的子集。通配符查询的 QueryParser 语法比较简单,还是使用 * 号和 ? 号。

var parser = new QueryParser("content", analyser);
var query = parser.parse("北京*");
System.out.println(query);
System.out.println(query.getClass());

--------
content:北京*
class org.apache.lucene.search.PrefixQuery

640?wx_fmt=png
图片

关于首字符带 * 号,QueryParser 还有一个例外情况,它内置了一个非常特殊的通配符 : ,它表示匹配所有的内容,也就是全文遍历 MatchAllDocsQuery。

var parser = new QueryParser("content", analyser);
var query = parser.parse("*:*");
System.out.println(query);
System.out.println(query.getClass());

------------
*:*
class org.apache.lucene.search.MatchAllDocsQuery

QueryParser 使用双引号来表示短语查询,默认的 slop 是零。

var parser = new QueryParser("content", analyser);
var query = parser.parse("\"动物世界\"");
System.out.println(query);
System.out.println(query.getClass());

-------------
content:"动物 世界"
class org.apache.lucene.search.PhraseQuery

var parser = new QueryParser("content", analyser);
var query = parser.parse("\"动物世界\"");
System.out.println(query);
System.out.println(query.getClass());

------------
content:北京大学
class org.apache.lucene.search.TermQuery

var query = parser.parse("\"动物世界\"~5");

----------
content:"动物 世界"~5

模糊查询也使用波浪号,但是不需要双引号了,如果希望设定模糊相似度(模糊因子),可以在波浪号后面增加一个浮点数,默认的模糊因子我也不知道是多少,但是我从代码中了解到默认的编辑距离是 2。如果设置了模糊因子 factor,编辑距离将会是 min((1-factor)*Length, 2),无论如何编辑距离也不会超过 2。

var parser = new QueryParser("title", analyser);
var query = parser.parse("动物世界~0.5");
System.out.println(query);
System.out.println(query.getClass());

-----------
title:动物世界~2
class org.apache.lucene.search.FuzzyQuery

为了支持更加复杂的组合逻辑,ParseQuery 提供了括号、AND、OR、NOT 这样的组合操作符,适当使用它们可以使得查询表达式逻辑更加清晰。

var parser = new QueryParser("content", analyser);
var query = parser.parse("(北京* OR 清华) AND 大学");
System.out.println(query);

-------------
+(title:北京* title:清华) +title:大学

var analyser = new HanLPAnalyzer();
var parser = new QueryParser("content", analyser);
var query = parser.parse("(北京* OR 清华) AND NOT 小学");
System.out.println(query);

-----------
+(content:北京 content:清华) -content:小学

我们在构造 QueryParser 时会传入一个目标字段名称,其实这个字段名称只是默认字段名称,如果表达式中没有指定字段名称,那么就会使用这个默认字段名称。如果不想使用默认字段名称,可以在表达式中使用字段限定符。

var parser = new QueryParser("content", analyser);
var query = parser.parse("(title:北京* OR title:清华) AND 大学");
System.out.println(query);

----------
+(title:北京* title:清华) +content:大学

字段加权

如果我希望在标题出现「北京大学」或者内容出现「北京大学」都可以,但是希望标题中出现的评分排序要靠前,那么可以对个别字段进行加权。下面我们来对比一下加权前后的效果

var parser = new QueryParser("content", analyser);
var query = parser.parse("title:科幻 OR 科幻");

var parser = new QueryParser("content", analyser);
var query = parser.parse("title:科幻^5.0 OR 科幻");

640?wx_fmt=png
图片

再看加权后

640?wx_fmt=png
图片

很明显评分显著发生了放大,还有一个很重要的改变就是标题中没有「科幻」的文章从前十中消失了。在文章搜索中,加权是一个必不可少的功能,但是究竟加权多大的值这又是另外一个我们暂时不好回答的问题,随着我们对搜索技术了解的逐步深入,在不久的未来也许我们会有答案。

Lucene硬核解析专题系列(三):查询解析与执行 Lucene的查询解析与执行是一个从文本到结果的精密过程。将用户输入转化为结构化查询,多种查询类型满足复杂需求,BM25评分模型确保结果相关性,高效执行搜索。下一篇文章将探讨性能优化与调优,揭示Lucene在高负载场景下的应对策略。 阅读详情

相关推荐

Lucene中各种Query的用法与场景分析

Lucene中各种Query的用法与场景分析 1.背景介绍 在现代信息时代,数据已经成为了企业和个人的重要资产。随着数据量的不断增长,有效地检索和利用这些数据变得至关重要。Apache Lucene是一个高性能、全功能的搜索引擎库,它提供了强大的索引和搜索功能,可以帮助我们快速地

AI大模型应用之禅 1111

lucene查询之 queryparser查询;及代码示例;代码实现;及查询语法解析

1.1. 使用queryparser查询 通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。Query对象执行的查询语法可通过System.out.println(query);查询。 需要使用到分析器。建议创建索引时使用的分析器和查询索引时使用的分析器要一致。   1.1.1. QueryParser 需要加

boss_way的博客 3338

分组背包问题(MCKP)三大算法对比:贪心、Dyer-Zemel和动态规划谁更强?

本文深入对比了分组背包问题(MCKP)的三大主流算法:贪心算法、Dyer-Zemel算法和动态规划。通过分析各自的原理、实现及性能表现,揭示了贪心算法速度快但非最优,动态规划精确但受限于规模,而Dyer-Zemel算法则在效率与最优性间取得了最佳平衡,是解决中等至大规模MCKP问题的首选方案。

vscode6remote的博客 226

构建各种Lucene Query

[code="java"] [size=x-large] 搜索流程中的第二步就是构建一个Query。下面就来介绍Query及其构建。 当用户输入一个关键字,搜索引擎接收到后,并不是立刻就将它放入后台开始进行关键字的检索,而应当首先对这个关键字进行一定的分析和处理,使之成为一种后台可以理解的形式,只有这样,才能提高检索的效率,同时检索出更加有效的结果。那么,在Lucene中,这种处理,...

小嘴冰凉 327

基于ESP32-C3的便携式血氧仪硬件与算法实现

血氧饱和度(SpO₂)监测是生理参数无创检测的核心技术之一,其原理基于光电容积脉搏波(PPG)信号中红光与红外光吸收比值的动态变化。该技术依赖高精度模拟前端、稳定光学激励及实时数字信号处理能力,在消费级健康设备中面临功耗、体积与测量鲁棒性的多重约束。ESP32-C3凭借集成LEDC、12位ADC与低功耗双核架构,成为PPG终端的理想主控平台;结合定制化指夹式光学探头与比率法血氧算法,可实现非诊断级但趋势可靠的日常健康监测。本文围绕硬件电路设计、电源管理策略与嵌入式信号处理流程展开,覆盖从LED驱动、跨阻放大

weixin_29025501的博客 132

小程序HTTPS证书配置踩坑记:为什么Android访问失败而iOS正常?

本文深入剖析了小程序开发中常见的跨平台网络问题:Android访问HTTPS接口失败而iOS正常。核心原因在于服务器(如Nginx)HTTPS证书链配置不完整,Android系统对此校验严格,而iOS相对宽松。文章提供了从问题诊断、使用在线工具检测到修复Nginx证书链配置的完整解决方案,并总结了HTTPS部署的最佳实践,帮助开发者从根本上避免此类“玄学”故障。

weixin_29207149的博客 395

lucene中document的所有id_Lucene 高阶查询的六脉神剑 —— QueryParser

上篇我们介绍了 Lucene 多样的查询模式,每一种都是相互独立的用来解决特定查询目标的 Query 对象。本节我们要将这些查询模式使用 QueryParser 组合起来进行合并查询 —— 用一个文本字符串表达式来表示所有的查询模式。QueryParser 的基本作用是将一个满足特定语法的字符串转换成相应的查询对象。我们可以不再需要使用组合对象的方式来手动构造复合逻辑查询,而是通过一个单...

weixin_33255691的博客 183

R语言pls包实战:手把手教你用偏最小二乘(PLS)搞定高维数据回归(附完整代码与数据标准化避坑指南)

本文详细介绍了如何使用R语言的pls包进行偏最小二乘(PLS)回归分析,特别针对高维数据回归问题。通过完整的代码示例和数据标准化避坑指南,帮助读者掌握从数据预处理到模型优化的全流程,解决实际应用中的常见问题。

weixin_42662605的博客 352

Lucene查询语法详解

Lucene提供了丰富的API来组合定制你所需要的查询器,同时也可以利用 Query Parser提供的强大的查询语法解析来构造你想要的查询器。本文章详细的介绍了Lucene的查询语法。通过Java语法分析器把一个查询字符串解析成 Lucene的查询器。在你选择使用Query Parser前,请考虑以下事项:如果你打算在程序中拼接查询语法串然后再利用Query Parser转换,那么强烈建议你利用...

zfsn7722483的专栏 1320

LSTM量化选股实战:从数据清洗到回测归因的工程化闭环

LSTM(长短期记忆网络)是一种专为建模长程依赖而设计的循环神经网络,其门控机制能有效应对金融时序数据的非线性、高噪声与动态演化特性。相比传统统计模型或简单RNN,LSTM在股价趋势建模中展现出更强的鲁棒性与泛化能力,尤其适合处理日频多因子时序信号。其技术价值不仅在于提升预测精度,更在于支撑可归因、可审计的量化策略工程实践——从特征构建、标签定义到滚动回测,每一步都需严防未来信息泄露与过拟合风险。典型应用场景包括A股多因子选股、行业轮动信号生成及Alpha组合优化。本文聚焦LSTM在真实量化场景中的落地难点

weixin_33158887的博客 400

SAP预扣税配置实战:从BP创建到外部接口集成的完整流程

本文详细拆解了SAP S/4HANA中预扣税配置与集成的完整实战流程。内容涵盖从业务伙伴(BP)架构下的数据存储理解、后台基础配置,到针对批量处理场景,如何绕过标准BAPI,采用直接更新核心表LFBW的策略进行高效开发。最后,文章探讨了与外部接口集成的多种模式与数据流设计,为财务顾问和ABAP开发人员提供了一套清晰、可落地的解决方案。

weixin_29204749的博客 418

Cap开源录屏工具:三分钟快速上手的终极指南

还在为复杂的录屏软件而烦恼吗?Cap作为一款现代化开源屏幕录制工具,以其极简设计和强大功能彻底改变了传统录屏体验。这款完全免费的工具支持Windows、macOS和Linux三大平台,让每个人都能轻松制作专业级屏幕录像。 ## 🎯 为什么选择Cap:开源录屏工具的革命 Cap不仅仅是另一个录屏软件,它是Loom的开源替代品,为你提供快速屏幕录制、精美的本地编辑、即时分享链接、评论、转录、分析

gitblog_00035的博客 637

【CASS精品教程】006:CASS7.1 道路设计参数文件打开无响应,提示roadpara解决办法,权威解决办法汇总

在用CASS7.1 软件进行断面法土方量计算,在生成断面图后,需要进行道路设计参数文件的设计,打开断面设计参数文件的时候,无响应,提示roadpara,如下所示: 道路设计参数文件 解决办法有三种 第一种方法:Win+R (1)64位系统:输入regsvr32 C:\Windows\SysWOW64\CellCtrl5.ocx,回车 (2)32位系统输入regsvr32 C:...

智慧空间实验室 1万+

查询字符串的解析—QueryParser类

对于搜索引擎(比如Google和百度)来讲,很多情况下只需要用户在输入框内输入所需查询的内容,然后再单击“搜索”就可以了,其余的事情全部交给搜索引擎去处理,最后搜索引擎会把检索到的结果显示出来。那么搜索引擎是怎样处理用户输入得符号串的呢?在Lucene中,这项工作就交给了QueryParser类来完成,它的作用就是把各种用户输入的符号串转为一个内部的Query或者一个Query组。虽然Luce

每天=生命的最后一天 3598

海康威视嵌入式最全面试题及参考答案(3万字长文)

主营业务:提供包括前端摄像头、后端存储设备、显示控制设备等在内的全方位视频监控解决方案。市场地位:在全球范围内享有较高的市场份额,在安防领域具有较强的竞争力。技术创新:持续投入研发,拥有多项核心技术和专利,特别是在视频处理算法、人工智能等方面取得了显著成果。社会责任:积极参与公共安全项目,为智慧城市、交通管理等领域提供技术支持和服务。国际业务:除了国内市场外,海康威视的产品和服务也销往全球多个国家和地区。面向对象编程。

大模型大数据攻城狮的专栏 1765

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

使用 Apache Lucene 搜索文本

481

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Lucene 高阶查询--QueryParser

QueryParser 的基本作用是将一个满足特定语法的字符串转换成相应的查询对象。我们可以不再需要使用组合对象的方式来手动构造复合逻辑查询,而是通过一个单行字符串就可以完成原先需要数行代码才能完成的查询功能。

小码农吗 379

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

理解Lucene中的Query

Query是一个接口,它有很多实现类。 QueryParser是Query解析器,用于将一个字符串解析为一个Query对象,这个Query对象可能属于TermQuery,也可能属于PhraseQuery、TermQuery、BooleanQuery等。可以通过Query对象的getClass()方法来查看这个对象到底是哪个实现类。 Lucene已经给我们提供了很多Query查询器,如Ph...

539

QueryParser 项目常见问题解决方案

QueryParser 项目是 Uber 开发的,它旨在提供对 Vertica、Hive 和 Presto SQL 语法的解析和分析功能。该项目使用 MIT 许可证,支持对 SQL 查询进行词法分析和语法分析,并生成一个通用的抽象语法树(AST),以表示不同方言的查询语句。主要的编程语言是 Haskell。 ## 2. 新手使用该项目需要特别注意的三个问题及解决步骤 ### 问题一:环境配置 ...

gitblog_00624的博客 401

lucene整理4 -- 各种Query

1. 各种Query 1.1. 概述 query.toString()查看原子查询 1.2. 使用特定的分析器搜索 [code="java"]IndexSearcher searcher = new IndexSearcher(path ); Hits hits = null; Query query = null; QueryParser parser =ne...

xiarilian12的博客 573

lucene-QueryParser

1、QueryParser在lucene2.0中所有操作建立在QueryParser实例的基础上2、String field="bookname";String queryStr="java struts";QueryParser parser=new QueryParser(field,new standardAnalyzer());Query q=parser.pars

深未来技术 514

Lucene5学习之QueryParser-Query解析器

    Lucene已经给我们提供了很多Query查询器,如PhraseQuery,SpanQuery,那为什么还要提供QueryParser呢?或者说设计QueryParser的目的是什么?QueryParser的目的就是让你从众多的Query实现类中脱离出来,因为Query实现类太多了,你有时候会茫然了,我到底该使用哪个Query实现类来完成我的查询需求呢,所以Lucene制定了一套Que...

嘿↗你的益达 954

lucene学习之queryParser

QueryParser queryParser = new QueryParser("desc", analyzer); queryParser.setAllowLeadingWildcard(true);//设置允许通配符?和*就可以使用 queryParser.setDefaultOperator(Operator.AND);默认or Query query = queryParse

小魏的博客 1217

Lucene中的各种Query实例

(1):TernQuery/**//* * Created on 2006-3-11 */package ch11;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.F

nobody_java的专栏 4219
上一篇: 要飞起来了,Lucene 高阶查询技巧
下一篇: 搞互联网压力真大,我需要给自己减减压
码洞
博客等级 码龄10年 41粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值