.net ElasticSearch-Sql 扩展类
官方提供的是java sdk,并支持jdbc方式的查询结果输出;但是却没有.net sdk的支持。
开发 ElasticSearch-Sql 第三方开源项目的.net sdk,未来集成入bsf框架。(已使用,但未进行大范围使用测试,欢迎交流并抛砖引玉)
参考ElasticSearch-Sql 开源地址:https://github.com/NLPchina/elasticsearch-sql
1)支持将查询结果转换成datatable形式,便于界面绑定和数据导出等。
2)代码简单易懂,便于改进并提高稳定性和性能。(拷贝立即使用)
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
/*by 车江毅 欢迎交流,一起完善之。.net 开源,因你更美好*/
namespace BSF.ElasticSearch
{
public class EsSqlProvider
{
private string url;
private HttpClient client = new HttpClient();
public EsSqlProvider(string ip,int port)
{
this.url = string.Format("http://{0}:{1}/_sql",ip,port);
} public EsSqlProvider(string url)
{
this.url = url.TrimEnd('/')+"/_sql";
} public Result Post(string sql)
{
//var http = new BSF.Api.HttpProvider();
//var dic = new Dictionary<string, string>();
//dic.Add("",sql); var content = new StringContent(sql);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var json = PostBase(content); return new BSF.Serialization.JsonProvider().Deserialize<Result>(json); } public DataTable Query(string sql)
{
var result = Post(sql);
if (result.aggregations != null && result.aggregations.Count > )
{
var first = result.aggregations.First();
//groupby 统计方式
if (first.Value != null && first.Value.buckets != null && first.Value.buckets.Count > )
{
DataTable dataTable = new DataTable("es-groupby");
//以第一列为准,填充列
{
var t = first.Value.buckets[];
dataTable.Columns.Add(new DataColumn(first.Key, ColumnType((GetValue((object)t["key"])).GetType())));
foreach (var c in t)
{
if (c.Key != "doc_count"&&c.Key!= "key")
{ dataTable.Columns.Add(new DataColumn(c.Key, (GetValue(c.Value)).GetType())); }
}
}
//填充值
foreach (var b in first.Value.buckets)
{
DataRow dataRow = dataTable.NewRow();
dataRow[first.Key] = b["key"];
foreach (var c in b)
{
if(dataTable.Columns.Contains(c.Key))
dataRow[c.Key] = GetValue(c.Value);
}
dataTable.Rows.Add(dataRow);
}
return dataTable; }
else if (first.Value != null&& first.Value.value!=null)
{
DataTable dataTable = new DataTable("es-aggregations");
//常规统计方式
foreach (var o in result.aggregations)
{
dataTable.Columns.Add(new DataColumn(o.Key, ColumnType((GetValue((object)o.Value)).GetType())));
}
DataRow dataRow = dataTable.NewRow();
foreach (var o in result.aggregations)
{
if (dataTable.Columns.Contains(o.Key))
dataRow[o.Key] = GetValue(o.Value);
}
dataTable.Rows.Add(dataRow);
return dataTable;
}
}
else if (result.sources != null && result.sources.Count > )
{
DataTable dataTable = new DataTable("es-sources");
var first = result.sources.First();
foreach (var item in ((Dictionary<string,dynamic>)first))
{
dataTable.Columns.Add(new DataColumn(item.Key, ColumnType((GetValue((Object)item.Value)).GetType())));
}
foreach (dynamic m in result.sources)
{
DataRow dataRow = dataTable.NewRow();
foreach (var item in ((Dictionary<string, dynamic>)m))
{
if (dataTable.Columns.Contains(item.Key))
dataRow[item.Key] = GetValue(item.Value);
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
return null;
} private Type ColumnType(Type type)
{
if (type.IsArray)
{
return typeof(string);
}
else
return type;
} private Object GetValue(Object value)
{
if (value != null && value is Array)
return new BSF.Serialization.JsonProvider().Serializer(value);
if (value != null && (value.GetType().IsValueType || value is String))
return value;
if (value != null && value is Dictionary<string, dynamic>)
{
var valuet = (Dictionary<string, dynamic>)value;
if( valuet.ContainsKey("value_as_string"))
return GetValue(valuet["value_as_string"]);
if (valuet.ContainsKey("value"))
return GetValue(valuet["value"]);
}
if (value != null && value.GetType().GetProperty("value")!=null)
{
var p= value.GetType().GetProperty("value_as_string");
if (p!=null&&p.GetValue(value)!=null)
return p.GetValue(value);
p = value.GetType().GetProperty("value");
if (p != null && p.GetValue(value) != null)
return p.GetValue(value);
}
return new BSF.Serialization.JsonProvider().Serializer(value);
} private Object GetPropertyValue(Object obj, string property)
{
var p = obj.GetType().GetProperty(property);
if (p != null)
return p.GetValue(obj);
return null;
} private string PostBase(HttpContent content)
{
//此处未来需要添加HttpClient连接池,复用连接
//using (var client = new HttpClient())
//{
var result = client.PostAsync(url, content).Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
return resultContent;
//}
} public class Result{ public Hits hits { get; set; }
public Dictionary<string, aggregation> aggregations {get;set;} public List<dynamic> sources { get {
List<dynamic> rs = new List<dynamic>();
foreach (var h in hits.hits)
{
rs.Add(h._source);
}
return rs;
} } public class aggvalue
{
public dynamic value { get; set; }
public string value_as_string { get; set; }
}
public class aggregation: aggvalue
{
public List<Dictionary<string, dynamic>> buckets { get; set; }
}
public class Hits {
public int total { get; set; }
public List<hit> hits { get; set; }
}
public class hit {
public string _index { get; set; }
public string _type { get; set; }
public string _id { get; set; } public string _score { get; set; } public dynamic _source { get; set; }
} }
}
}
欢迎交流,为了更好的完善之,开源QQ群: .net 开源基础服务 238543768
by 车江毅
.net ElasticSearch-Sql 扩展类的更多相关文章
- Mybatis逆向生成使用扩展类
1.背景介绍 用的mybatis自动生成的插件,然而每次更改数据库的时候重新生成需要替换原有的mapper.xml文件,都要把之前业务相关的sql重新写一遍,感觉十分麻烦,就想着把自动生成的作为一个基 ...
- 针对thinkphp 5框架存储过程bug而重写的存储过程的扩展类
近期用tp5框架调取存储过程发现有bug,借鉴了一些官方的函数.以及找了个mysqli的类把存储过程重新写了个扩展类,下面两个类直接放置项目extend目录的stored(这个文件夹名称请按个人习惯命 ...
- C# 扩展类
C# 中提供一个非常实用的供能,扩展方法(Extension method) 扩展方法是通过额外的静态方法扩展现有的类型.通过扩展方法,可以对已有类型做自己想做的相关扩展.方法:定义静态类,扩展方法也 ...
- 一个简单的ORM制作(SQL帮助类)
一个简单的ORM制作大概需要以下几个类: SQL执行类 CURD操作类 其他酱油类 先从SQL执行类说起,可能会涉及数据库的迁移等问题,所以需要定义一个接口以方便迁移到其他数据库, 事务没提供命名,若 ...
- tp中调用PHP系统扩展类
例如使用Redis扩展类: use Reids; $redis = new Redis();
- Java+7入门经典 - 6 扩展类与继承 Part 1/2
第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...
- Thinkphp编辑器扩展类kindeditor用法
一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp站点项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们拷贝到你的站点项目的Th ...
- 扩展javascript扩展(类,对象,原型)
扩展javascript扩展(类,对象,原型)
- 使用JDBC连接ElasticSearch6.3(ElasticSearch SQL JDBC)
使用JDBC连接ElasticSearch6.3(ElasticSearch SQL JDBC) https://blog.csdn.net/scgaliguodong123_/article/det ...
- 颜色扩展类--ColorExtensions
/// <summary> /// 颜色扩展类 /// </summary> public static class ColorExtensions { /// <sum ...
随机推荐
- Java中的系统时间
System.currentTimeMillis()产生一个当前的毫秒,这个毫秒其实就是自1970年1月1日0时起的毫秒数,Date()其实就是相当于Date(System.currentTimeMi ...
- Android计时器实现
Wyy.java package com.test; import android.app.Activity;import android.app.Service;import android.os. ...
- java io 流
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- Jmeter-WINDOWS下的配置部署
前提:已配置安装JDK环境及已部署TOMCAT. 解压apache-jmeter-2.9.zip文件至目录,我的是D:\Program Files目录. 点击我的电脑----属性----高级----环 ...
- ORA-12638: 身份证明检索失败 解决方法
用PL/SQL或Navicat连接本地或远程Oracle数据库的时候报错:ORA-12638: 身份证明检索失败 解决方法: 开始 -> 所有程序 -> Oracle - Oracle_h ...
- SICP-Elements of program
编程语言=组合简单形成复杂的工具 简单的声明和表达式 简单元素之间的组合方式 组合后元素的抽象方式 程序=数据+函数 数据是我们要处理的内容 函数是我们处理数据的方式 函数式与中缀式 函数式不会出现歧 ...
- 抓包工具 - Fiddler(如何捕获Android数据包)
如何捕获Android数据包 一.移动设备访问网络原理 先看看移动设备是怎么去访问网络,如图1所示,可以看到,移动端的数据包是从wifi出去的. 图1(移动设备访问网络) 所以我们可以把自己的电脑开启 ...
- web开发中前后端传值
在JavaScript中,页面与页面间的传值需要注意. 比如,我们通过url向下个页面进行传一个数字时,到下个页面进行解析出来后可能是一个字符串.这样会导致一个现象.调试时,发现我要传的值的确传过来了 ...
- 文件存储B+树
文件存储要选用B+树这样的数据结构 “文件存储要选用B+树这样的数据结构”——没记错的话,这是严蔚敏那本数据结构书上的一句结论.不知道是我没细看还是她没细讲,反正当时纯粹应试地记了这么个结论.不求甚解 ...
- 一张图告诉你 canvas 中的 miterLimit 代表着什么
一图胜千言, 图中有一条路径path, 沿着路径描了一条宽度为 width 的边, miterLimit 代表的是, 比例 ab/ac, 其中ac的长度为 1/2 width 来看 mdn 上的描述, ...