查询的时候有自己的查询格式,为了统一并且方便的搜索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的更多相关文章

  1. Lucene中的 Query对象

    "Lucene中的 Query对象": 检 索前,需要对检索字符串进行分析,这是由queryparser来完成的.为了保证查询的正确性,最好用创建索引文件时同样的分析器. quer ...

  2. 理解Lucene中的Query

    Query是一个接口,它有很多实现类. QueryParser是Query解析器,用于将一个字符串解析为一个Query对象,这个Query对象可能属于TermQuery,也可能属于PhraseQuer ...

  3. Lucene Query Term Weighting

    方法 public static Query TermWeighting(Query tquery,Map<String,Float>term2weight){ BooleanQuery ...

  4. Lucene 06 - 使用Lucene的Query API查询数据

    目录 1 Query对象的创建(方式一): 使用子类对象 1.1 常用的Query子类对象 1.2 常用的Query子类对象使用 1.2.1 使用TermQuery 1.2.2 使用NumericRa ...

  5. Lucene 搜索功能

    搜索过程 图解: 主要 API: IndexSearcher:    //所有搜索都通过 IndexSearcher 进行,他们将调用该类中重载的 search() 方法 Query:         ...

  6. Lucene.net 多条件查询搜索

    最近一直在研究lucene,目的是想让网站实现像搜索引擎那样的搜索,可以快速.准确的帮用户查询出想要的结果.废话不多说,上代码实例: 1.利用BooleanQuery进行多条件搜索(比较灵活)   L ...

  7. 初识Lucene.net

    最近想提高下自己的能力,也是由于自己的项目中需要用到Lucene,所以开始接触这门富有挑战又充满新奇的技术.. 刚刚开始,只是写了个小小的demo,用了用lucene,确实很好   创建索引 Data ...

  8. org.apache.lucene.queryParser.ParseException: Encountered "<EOF>" at line 1, column 0.

    如果出现了下列错误,那是因为用错了函数.把queryParser.Query改称queryParser.parse就通过了 org.apache.lucene.queryParser.ParseExc ...

  9. lucene&solr-day1

        全文检索课程 Lucene&Solr(1) 1.   计划 第一天:Lucene的基础知识 1.案例分析:什么是全文检索,如何实现全文检索 2.Lucene实现全文检索的流程 a)   ...

随机推荐

  1. CSS3与页面布局学习总结

    目录 一.BFC与IFC 1.1.BFC与IFC概要 1.2.如何产生BFC 1.3.BFC的作用与特点 二.定位 2.2.relative 2.3.absolute 2.4.fixed 2.5.z- ...

  2. 【设计模式】Java版设计模式的类图汇总

    Abstract Factory Intent: Provide an interface for creating families of related or dependent objects ...

  3. C语言实现冒泡排序-整数排序

    我一直觉得排序算法挺重要的,但是却没有深入的去理解它: 没有深入理解就无法用代码将它实现: 在腾讯的在线模拟考试中就有一题问到冒泡排序: 我几乎是傻眼了!我知道这样的问题是最基础的: 无论过去怎样现在 ...

  4. iOS之富文本

    之前做项目时遇到一个问题: 使用UITextView显示一段电影的简介,由于字数比较多,所以字体设置的很小,行间距和段间距也很小,一大段文字挤在一起看起来很别扭,想要把行间距调大,结果在XCode中查 ...

  5. css3过渡transition

    过渡:transition transition:transition-property/duration/timing-function/delay的缩写. transition : <'tr ...

  6. java获取静态页面内容

    package collection_map; import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.F ...

  7. ASP.NET MVC4+EasyUI+EntityFrameWork5权限管理系统——菜单模块的实现(二)

    ASP.NET MVC4+EasyUI+EntityFrameWork5权限管理系统——数据库的设计(一) 菜单和模块是在同一个表中,采用的是树形结构,模块菜单表结构如下代码: USE [Permis ...

  8. HTML之总结

    基础结构 基础标签有HTML,head,body. 合格的的HTML页面: <!DOCTYPE html> <html lang="en"> <hea ...

  9. android: 文件存储

    数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑 关机的情况下,这些数据仍然不会丢失.保存在内存中的数据是处于瞬时状态的,而保存在 存储设备中的数据是处于持久状态的,持久化 ...

  10. HTML 邮件链接,超链接发邮件

    在网页中可以设置如“联系我们”.“问题反馈”等所谓的邮箱链接,类似网页超链接,只是可以直接打开默认邮箱程序. 使用<a href="mailto:youEMail@xxx.yyy&qu ...