解析表达式到lucene.net的Query
查询的时候有自己的查询格式,为了统一并且方便的搜索lucene.net 于是就写了个解析格式,大体上覆盖了几乎所有的lucene.net的query了。当然少了公共扩展库里包含的regexQuery,这个有个坑,平时的时候用的比较少,所以就等下次专门写一篇regexQuery的用法吧。
public class SearchModule { private static readonly Regex _all = new Regex(@"^(-?\d+\.\d{1,8}|-?\d+)~(-?\d+\.\d{1,8}|-?\d+)$"); private static readonly Regex _num = new Regex(@"^(-?\d+\.\d{1,8}|-?\d+)$", RegexOptions.Compiled | RegexOptions.Singleline); public string Module { get; set; } [JsonConverter(typeof(StringEnumConverter))] public Occur Occur { get; set; } private RelationMapper[] _relation; public RelationMapper[] relation { get { return this._relation ?? new RelationMapper[] { }; } set { _relation = value; } } private static Query UpQueryMethod(string key, string value) { if (_num.IsMatch(value) == false) throw new Exception("错误的表达式"); else { if (value.Contains('.')) { return NumericRangeQuery.NewDoubleRange(key, double.Parse(value), double.MaxValue, false, false); } else { return NumericRangeQuery.NewIntRange(key, int.Parse(value), int.MaxValue, false, false); } } } private static Query UpEqualQueryMethod(string key, string value) { if (_num.IsMatch(value) == false) throw new Exception("错误的表达式"); else { if (value.Contains('.')) { return NumericRangeQuery.NewDoubleRange(key, double.Parse(value), double.MaxValue, true, true); } else { return NumericRangeQuery.NewIntRange(key, int.Parse(value), int.MaxValue, true, true); } } } private static Query DownQueryMethod(string key, string value) { if (_num.IsMatch(value) == false) throw new Exception("错误的表达式"); else { if (value.Contains('.')) { return NumericRangeQuery.NewDoubleRange(key, double.MinValue, double.Parse(value), false, false); } else { return NumericRangeQuery.NewIntRange(key, int.MinValue, int.Parse(value), false, false); } } } private static Query DownEqualQueryMethod(string key, string value) { if (_num.IsMatch(value) == false) throw new Exception("错误的表达式"); else { if (value.Contains('.')) { return NumericRangeQuery.NewDoubleRange(key, double.MinValue, double.Parse(value), true, true); } else { return NumericRangeQuery.NewIntRange(key, int.MinValue, int.Parse(value), true, true); } } } private static Query RangeQueryMethod(string key, string value) { if (_all.IsMatch(value) == false) throw new Exception("错误的表达式"); else { var group = _all.Match(value).Groups; var startValue = group[1].Value; var endValue = group[2].Value; if (startValue.Contains('.')) { var sValue = double.Parse(startValue); var eValue = double.Parse(endValue); return NumericRangeQuery.NewDoubleRange(key, sValue > eValue ? eValue : sValue, sValue > eValue ? sValue : eValue, true, true); } else { var sValue = int.Parse(startValue); var eValue = int.Parse(endValue); return NumericRangeQuery.NewIntRange(key, sValue > eValue ? eValue : sValue, sValue > eValue ? sValue : eValue, true, true); } } } private static Query DefaultMethod(string key, string value) { return new TermQuery(new Term(key, value)); } public static Query MultiPhraseQueryMethod(string key, string value) { var mulit = new MultiPhraseQuery(); mulit.Add(new Term(key, value)); return mulit; } public override string ToString() { Func<RelationMapper, Query> queryfunc = (r) => { var c = r.RelationChar; Func<string, string, Query> method; switch (c) { case ">": method = (key, value) => UpQueryMethod(key, value); break; case ">=": method = (key, value) => UpEqualQueryMethod(key, value); break; case "<": method = (key, value) => DownQueryMethod(key, value); break; case "<=": method = (key, value) => DownEqualQueryMethod(key, value); break; case "=": method = (key, value) => DefaultMethod(key, value); break; case "at": method = (key, value) => RangeQueryMethod(key, value); break; case "contains": method = (key, value) => MultiPhraseQueryMethod(key, value); break; case "like": method = (key, value) => DefaultMethod(key, value); break; default: throw new Exception("未知的查询表达式"); } return method(r.Key, r.Value); }; Func<IEnumerable<RelationMapper>, Query> func = (r) => { var query = new BooleanQuery(); foreach (var item in r) { var tquery = queryfunc(item); if (item.Occur == Occur.AND || item.Occur == Occur.OR) query.Add(tquery, Lucene.Net.Search.Occur.MUST); else if (item.Occur == Occur.NOT) query.Add(tquery, Lucene.Net.Search.Occur.MUST_NOT); } return query; }; var orcount = this.relation.Count(r => r.Occur == Occur.OR); Query[] result = new Query[orcount + 1]; if (orcount == 0) { result[0] = func(this.relation); } else { var last = 0; var at = 0; for (int i = 0; i < this.relation.Length; i++) { if (i == 0) { continue; } if (this.relation[i].Occur == Occur.OR) { result[at] = func(this.relation.Take(i).Skip(last)); at++; last = i; } } if (last != this.relation.Length) { result[at] = func(this.relation.Take(this.relation.Length).Skip(last)); } } Query resultQuery; if (result.Count() == 1) { resultQuery = result[0]; } else { var bquery = new BooleanQuery(); foreach (var query in result) { bquery.Add(query, Lucene.Net.Search.Occur.SHOULD); } resultQuery = bquery; } return resultQuery.ToString(); } }
解析表达式到lucene.net的Query的更多相关文章
- Lucene中的 Query对象
"Lucene中的 Query对象": 检 索前,需要对检索字符串进行分析,这是由queryparser来完成的.为了保证查询的正确性,最好用创建索引文件时同样的分析器. quer ...
- 理解Lucene中的Query
Query是一个接口,它有很多实现类. QueryParser是Query解析器,用于将一个字符串解析为一个Query对象,这个Query对象可能属于TermQuery,也可能属于PhraseQuer ...
- Lucene Query Term Weighting
方法 public static Query TermWeighting(Query tquery,Map<String,Float>term2weight){ BooleanQuery ...
- Lucene 06 - 使用Lucene的Query API查询数据
目录 1 Query对象的创建(方式一): 使用子类对象 1.1 常用的Query子类对象 1.2 常用的Query子类对象使用 1.2.1 使用TermQuery 1.2.2 使用NumericRa ...
- Lucene 搜索功能
搜索过程 图解: 主要 API: IndexSearcher: //所有搜索都通过 IndexSearcher 进行,他们将调用该类中重载的 search() 方法 Query: ...
- Lucene.net 多条件查询搜索
最近一直在研究lucene,目的是想让网站实现像搜索引擎那样的搜索,可以快速.准确的帮用户查询出想要的结果.废话不多说,上代码实例: 1.利用BooleanQuery进行多条件搜索(比较灵活) L ...
- 初识Lucene.net
最近想提高下自己的能力,也是由于自己的项目中需要用到Lucene,所以开始接触这门富有挑战又充满新奇的技术.. 刚刚开始,只是写了个小小的demo,用了用lucene,确实很好 创建索引 Data ...
- org.apache.lucene.queryParser.ParseException: Encountered "<EOF>" at line 1, column 0.
如果出现了下列错误,那是因为用错了函数.把queryParser.Query改称queryParser.parse就通过了 org.apache.lucene.queryParser.ParseExc ...
- lucene&solr-day1
全文检索课程 Lucene&Solr(1) 1. 计划 第一天:Lucene的基础知识 1.案例分析:什么是全文检索,如何实现全文检索 2.Lucene实现全文检索的流程 a) ...
随机推荐
- 虚拟机锁定文件失败,开启模块snapshot失败解决办法
今天由于没有正常关闭虚拟机,导致出现打开虚拟机提示:锁定文件失败 虚拟机开启模块snapshot失败,后来从网上找打了资料解决了.解决办法:一:打开你存放虚拟机系统文件的文件夹,注意,是系统文件,不是 ...
- Atitti.java exp ast java表达式语法ast构造器
Atitti.java exp ast java表达式语法ast构造器 /atiplat_cms/src/com/attilax/lang/AstParser.java 原理 分割tokens_sli ...
- 重新签名IPA ( iPhone )
提示:暂时不能用了,企业证书滥用 ios 企业证书 ipa 重新签名发布 1. 应用场景 当前有一个 未用企业证书签名的 ipa 文件,默认是不可以直接安装到设备上的:我们需要用企业版证书签名: 当前 ...
- javaweb学习总结(八)——HttpServletResponse对象(二)
一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类,
- 修改Oracle并行度的方法
Oracle并行度默认为1,适当修改并行度对提高性能有很大帮助 1.查看并行度 select table_name,degree from user_tables; --并行度按照用户表分别设置 2. ...
- Android图片处理-相机、相处简单调用
安卓开发中,常常需要使用到手机相机拍照.或者相册上传头像等等.通过使用Intent,我们很方便地获得相机.相册里面的图片: 1.相机调用,通过设置File文件路径和文件名,可以将拍照得到的图片保存下来 ...
- [IOS]IOS UI指南
[IOS]IOS UI指南 众所周知,IOS的界面设计,越来越流行,可以说都形成了一个标准,搜集了一些资料,供自己以后学习使用! iOS Human Interface Guidelines (中文翻 ...
- [轉]redis;mongodb;memcache三者的性能比較
先说我自己用的情况: 最先用的memcache ,用于键值对关系的服务器端缓存,用于存储一些常用的不是很大,但需要快速反应的数据 然后,在另一个地方,要用到redis,然后就去研究了下redis. 一 ...
- RFID 读写器 Reader Writer Cloner
RFID读写器的工作原理 RFID的数据采集以读写器为主导,RFID读写器是一种通过无线通信,实现对标签识别和内存数据的读出和写入操作的装置. 读写器又称为阅读器或读头(Reader).查询器(Int ...
- Facebook is Hiring!
I am a software engineer in Facebook. I joined Facebook a year ago and now doing some iOS stuff. If ...