解析表达式到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) ...
随机推荐
- jQuery演示10种不同的切换图片列表动画效果以及tab动画演示 2
很常用的一款特效纯CSS完成tab实现5种不同切换对应内容效果 实例预览 下载地址 实例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ...
- H5图片裁剪升级版(手机版)
前段时间做了个跟裁剪相关的活动<用H5中的Canvas等技术制作海报>,这次公司要做个与奥运相关的活动,扫车牌赢奖. 于是我就在上一个活动的基础上,将代码重新封装一下,并且将计算方式写的更 ...
- LINQ-to-SQL那点事~利用反射在LINQ-to-SQL环境中实现Ado.net的CURD操作
回到目录 对于linq to sql提供的CURD操作,给我们的感觉就是简单,容易使用,更加面向对象,不用拼SQL语句了,这些好处都表示在处理单条实体或者集合长度小的情况下,如果有一个1000条的集合 ...
- 利用nodejs模块缓存机制创建“全局变量”
在<深入浅出nodejs>有这样一段(有部分增减): 1.nodejs引入模块分四个步骤 路径分析 文件定位 编译执行 加入内存 2.核心模块部分在node源代码的编译过程中就编译成了二级 ...
- 如何引用jQuery实现下拉列表,点击展开,点击关闭。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- C语言实现快速排序
我觉得冒泡排序是比较简单的: 所以今天我们实现一个叫做快速排序的: Problem 你想要将(4,3,5,1,2)排序成(1,2,3,4,5) 你决定使用最简单的快速排序: Solution 首先,打 ...
- JS open App(未安装就跳转下载页面)
直接上代码var APPCommon = { downAppURl : "http://**/",//下载APP地址 downWeixin: "http://**&quo ...
- 详解eNSP下的PPP之MP、PAP/CHAP认证实验配置
一.PPP MP实验(用虚拟模板配置) 1.拓扑图
- Meanshift filter实现简单图片的卡通化效果
利用Meanshift filter和canny边缘检测的效果,可以实现简单的图片的卡通化效果.简单的说,就是用Meanshift filter的结果减去canny算法的结果得到卡通化的效果. ...
- Win7任务栏图标大小调整为等宽
打开注册表,找到HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics,新建DWORD,输入MinWidth,大图标设为56,小图标设定为36: 参 ...