标签:ica scan 响应 equals images 排序 pat ring ges
Elasticsearch.Net与NEST是Elasticsearch为C#提供的一套客户端驱动,方便C#调用Elasticsearch服务接口。Elasticsearch.Net是较基层的对Elasticsearch服务接口请求响应的实现,NEST是在前者基础之上进行的封装。本文是针对NEST的使用的总结。
Install-Package NEST
包含以下dll
NEST.dll
Elasticsearch.Net.dll
Newtonsoft.Json.dll
在Elasticsearch中,文档(Document)归属于一种类型(type),而这些类型存在于索引(index)中.
类比传统关系型数据库:
Relational DB -> Databases -> Tables -> Rows -> Columns Elasticsearch -> Indices -> Types -> Documents -> Fields
mm (毫米)cm (厘米)m (米)km (千米)in (英寸)ft (英尺)yd (码)mi (英里)nmi or NM (海里)s => s
.Query(q => q
.Term(p => p.Name, "elasticsearch")
)
var searchRequest = new SearchRequest<VendorPriceInfo>
{
Query = new TermQuery
{
Field = "name",
Value = "elasticsearch"
}
};
//单node
Var node = new Uri(“……”);
var settings = new ConnectionSettings(node);
//多uri
Var uris = new Uri [] {
new Uri(“……”),
new Uri(“……”)
};
//多node
Var nodes = new Node [] {
new Node (new Uri(“……”)),
new Node (new Uri(“……”))
};
var pool = new StaticConnectionPool(nodes);
var pool = new StaticConnectionPool(uris);
var settings = new ConnectionSettings(pool);
var client = new ElasticClient(settings);
//对单节点请求 IConnectionPool pool = new SingleNodeConnectionPool(urls.FirstOrDefault()); //请求时随机请求各个正常节点,不请求异常节点,异常节点恢复后会重新被请求 IConnectionPool pool = new StaticConnectionPool(urls); IConnectionPool pool = new SniffingConnectionPool(urls); //false.创建客户端时,随机选择一个节点作为客户端的请求对象,该节点异常后不会切换其它节点 //true,请求时随机请求各个正常节点,不请求异常节点,但异常节点恢复后不会重新被请求 pool.SniffedOnStartup = true; //创建客户端时,选择第一个节点作为请求主节点,该节点异常后会切换其它节点,待主节点恢复后会自动切换回来 IConnectionPool pool = new StickyConnectionPool(urls);
索引选择
var settings = new ConnectionSettings().DefaultIndex("defaultindex");
方式2:
var settings = new ConnectionSettings().MapDefaultTypeIndices(m => m.Add(typeof(Project), "projects") );
方式3:
client.Search<VendorPriceInfo>(s => s.Index("test-index"));
client.Index(data,o=>o.Index("test-index"));
优先级:方式3 > 方式2 > 方式1
1) 默认以“Id”字段值作为索引唯一Id值,无“Id”属性,Es自动生成唯一Id值,添加数据时统一类型数据唯一ID已存在相等值,将只做更新处理。
注:自动生成的ID有22个字符长,URL-safe, Base64-encoded string universally unique identifiers, 或者叫UUIDs。
2) 标记唯一Id值
[ElasticsearchType(IdProperty = "priceID")]
public class VendorPriceInfo
{
public Int64 priceID { get; set; }
public int oldID { get; set; }
public int source { get; set; }
}
3) 索引时指定
client.Index(data, o => o.Id(data.vendorName));
优先级: 3) > 2) > 1)
1) 默认类型为索引数据的类名(自动转换为全小写)
2) 标记类型
[ElasticsearchType(Name = "datatype")]
public class VendorPriceInfo
{
public Int64 priceID { get; set; }
public int oldID { get; set; }
public int source { get; set; }
}
3) 索引时指定
client.Index(data, o => o.Type(new TypeName() { Name = "datatype", Type = typeof(VendorPriceInfo) }));
或
client.Index(data, o => o.Type<MyClass>());//使用 2)标记的类型
优先级:3)> 2) > 1)
client.CreateIndex("test2");
//基本配置
IIndexState indexState=new IndexState()
{
Settings = new IndexSettings()
{
NumberOfReplicas = 1,//副本数
NumberOfShards = 5//分片数
}
};
client.CreateIndex("test2", p => p.InitializeUsing(indexState));
//创建并Mapping
client.CreateIndex("test-index3", p => p.InitializeUsing(indexState).Mappings(m => m.Map<VendorPriceInfo>(mp => mp.AutoMap())));
注:索引名称必须小写
client.IndexExists("test2");
删除:
client.DeleteIndex("test2");
Open/Close:
client.OpenIndex("index");
client.CloseIndex("index");
每个类型拥有自己的映射(mapping)或者模式定义(schema definition)。一个映射定义了字段类型,每个字段的数据类型,以及字段被Elasticsearch处理的方式。映射还用于设置关联到类型上的元数据。
var resule = client.GetMapping<VendorPriceInfo>();
/// <summary>
/// VendorPrice 实体
/// </summary>
[ElasticsearchType(IdProperty = "priceID", Name = "VendorPriceInfo")]
public class VendorPriceInfo
{
[Number(NumberType.Long)]
public Int64 priceID { get; set; }
[Date(Format = "mmddyyyy")]
public DateTime modifyTime { get; set; }
/// <summary>
/// 如果string 类型的字段不需要被分析器拆分,要作为一个正体进行查询,需标记此声明,否则索引的值将被分析器拆分
/// </summary>
[String(Index = FieldIndexOption.NotAnalyzed)]
public string pvc_Name { get; set; }
/// <summary>
/// 设置索引时字段的名称
/// </summary>
[String(Name = "PvcDesc")]
public string pvc_Desc { get; set; }
/// <summary>
/// 如需使用坐标点类型需添加坐标点特性,在maping时会自动映射类型
/// </summary>
[GeoPoint(Name = "ZuoBiao",LatLon = true)]
public GeoLocation Location { get; set; }
}
//根据对象类型自动映射
var result= client.Map<VendorPriceInfo>(m => m.AutoMap());
//手动指定
var result1 = client.Map<VendorPriceInfo>(m => m.Properties(p => p
.GeoPoint(gp => gp.Name(n => n.Location)// 坐标点类型
.Fielddata(fd => fd
.Format(GeoPointFielddataFormat.Compressed)//格式 array doc_values compressed disabled
.Precision(new Distance(2, DistanceUnit.Meters)) //精确度
))
.String(s => s.Name(n => n.b_id))//string 类型
));
//在原有字段下新增字段(用于存储不同格式的数据,查询方法查看SearchBaseDemo)
//eg:在 vendorName 下添加无需分析器分析的值 temp
var result2 = client.Map<VendorPriceInfo>(
m => m
.Properties(p => p.String(s => s.Name(n => n.vendorName).Fields(fd => fd.String(ss => ss.Name("temp").Index(FieldIndexOption.NotAnalyzed))))));
注:映射时已存在的字段将无法重新映射,只有新加的字段能映射成功。
所以我们也可以使用Index来更新已存在文档,只需对应文档的唯一id。
var data = new VendorPriceInfo() { vendorName = "测试"};
client.Index(data);
var datas = new List<VendorPriceInfo> {
new VendorPriceInfo(){priceID = 1,vendorName = "test1"},
new VendorPriceInfo(){priceID = 2,vendorName = "test2"}};
client.IndexMany(datas);
DocumentPath<VendorPriceInfo> deletePath=new DocumentPath<VendorPriceInfo>(7);
client.Delete(deletePath);
或
IDeleteRequest request = new DeleteRequest("test3", "vendorpriceinfo", 0);
client.Delete(request);
Indices indices = "test-1";
Types types = "vendorpriceinfo";
//批量删除 需要es安装 delete-by-query插件
var result = client.DeleteByQuery<VendorPriceInfo>(indices, types,
dq =>
dq.Query(
q =>
q.TermRange(tr => tr.Field(fd => fd.priceID).GreaterThanOrEquals("5").LessThanOrEquals("10")))
);
DocumentPath<VendorPriceInfo> deletePath=new DocumentPath<VendorPriceInfo>(2);
Var response=client.Update(deletePath,(p)=>p.Doc(new VendorPriceInfo(){vendorName = "test2update..."}));
//或
IUpdateRequest<VendorPriceInfo, VendorPriceInfo> request = new UpdateRequest<VendorPriceInfo, VendorPriceInfo>(deletePath)
{
Doc = new VendorPriceInfo()
{
priceID = 888,
vendorName = "test4update........"
}
};
var response = client.Update<VendorPriceInfo, VendorPriceInfo>(request);
IUpdateRequest<VendorPriceInfo, VendorPriceInfoP> request = new UpdateRequest<VendorPriceInfo, VendorPriceInfoP>(deletePath)
{
Doc = new VendorPriceInfoP()
{
priceID = 888,
vendorName = "test4update........"
}
};
var response = client.Update(request);
IUpdateRequest<VendorPriceInfo, object> request = new UpdateRequest<VendorPriceInfo, object>(deletePath)
{
Doc = new
{
priceID = 888,
vendorName = " test4update........"
}
};
var response = client.Update(request);
//或
client.Update<VendorPriceInfo, object>(deletePath, upt => upt.Doc(new { vendorName = "ptptptptp" }));
注:更新时根据唯一id更新
var response = client.Get(new DocumentPath<VendorPriceInfo>(0));
//或
var response =
client.Get(new DocumentPath<VendorPriceInfo>(0),pd=>pd.Index("test4").Type("v2"));
//多个
var response = client.MultiGet(m => m.GetMany<VendorPriceInfo>(new List<long> { 1, 2, 3, 4 }));
注:获取时根据唯一id获取
var result = client.Search<VendorPriceInfo>(
s => s
.Explain() //参数可以提供查询的更多详情。
.FielddataFields(fs => fs //对指定字段进行分析
.Field(p => p.vendorFullName)
.Field(p => p.cbName)
)
.From(0) //跳过的数据个数
.Size(50) //返回数据个数
.Query(q =>
q.Term(p => p.vendorID, 100) // 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型):
&&
q.Term(p => p.vendorName.Suffix("temp"), "姓名") //用于自定义属性的查询 (定义方法查看MappingDemo)
&&
q.Bool( //bool 查询
b => b
.Must(mt => mt //所有分句必须全部匹配,与 AND 相同
.TermRange(p => p.Field(f => f.priceID).GreaterThan("0").LessThan("1"))) //指定范围查找
.Should(sd => sd //至少有一个分句匹配,与 OR 相同
.Term(p => p.priceID, 32915),
sd => sd.Terms(t => t.Field(fd => fd.priceID).Terms(new[] {10, 20, 30})),//多值
//||
//sd.Term(p => p.priceID, 1001)
//||
//sd.Term(p => p.priceID, 1005)
sd => sd.TermRange(tr => tr.GreaterThan("10").LessThan("12").Field(f => f.vendorPrice))
)
.MustNot(mn => mn//所有分句都必须不匹配,与 NOT 相同
.Term(p => p.priceID, 1001)
,
mn => mn.Bool(//bool 过滤 ,bool 查询与 bool 过滤相似,用于合并多个查询子句。不同的是,bool 过滤可以直接给出是否匹配成功, 而bool 查询要计算每一个查询子句的 _score (相关性分值)。
bb=>bb.Must(mt=>mt
.Match(mc=>mc.Field(fd=>fd.carName).Query("至尊"))
))
)
)
)//查询条件
.Sort(st => st.Ascending(asc => asc.vendorPrice))//排序
.Source(sc => sc.Include(ic => ic
.Fields(
fd => fd.vendorName,
fd => fd.vendorID,
fd => fd.priceID,
fd => fd.vendorPrice))) //返回特定的字段
);
//TResult
var result1 = client.Search<VendorPriceInfo, VendorPriceInfoP>(s => s.Query(
q => q.MatchAll()
)
.Size(15)
);
或
var result = client.Search<VendorPriceInfo>(new SearchRequest()
{
Sort =new List<ISort>
{
new SortField { Field = "vendorPrice", Order = SortOrder.Ascending }
},
Size = 10,
From = 0,
Query = new TermQuery()
{
Field = "priceID",
Value = 6
}
||
new TermQuery(
{
Field = "priceID",
Value = 8
}
});
//分页最大限制(from+size<=10000)
int pageSize = 10; int pageIndex = 1; var result = client.Search<VendorPriceInfo>(s => s.Query(q => q .MatchAll()) .Size(pageSize) .From((pageIndex - 1) * pageSize) .Sort(st => st.Descending(d => d.priceID)));
string scrollid = "";
var result = client.Search<VendorPriceInfo>(s => s.Query(q => q.MatchAll())
.Size(100)
.SearchType(SearchType.Scan)
.Scroll("1m"));//scrollid过期时间
//得到滚动扫描的id
scrollid = result.ScrollId;
//执行滚动扫描得到数据 返回数据量是 result.Shards.Successful*size(查询成功的分片数*size)
result = client.Scroll<VendorPriceInfo>("1m", scrollid);
//得到新的id
scrollid = result.ScrollId;
// 在原分值基础上 设置不同匹配的加成值 具体算法为lucene内部算法
var result = client.Search<VendorPriceInfo>(s => s .Query(q => q.Term(t => t .Field(f => f.cityID).Value(2108).Boost(4)) || q.Term(t => t .Field(f => f.pvcId).Value(2103).Boost(1)) ) .Size(3000) .Sort(st => st.Descending(SortSpecialField.Score)) );
//使用functionscore计算得分
var result1 = client.Search<VendorPriceInfo>(s => s .Query(q=>q.FunctionScore(f=>f
//查询区 .Query(qq => qq.Term(t => t .Field(fd => fd.cityID).Value(2108)) || qq.Term(t => t .Field(fd => fd.pvcId).Value(2103)) ) .Boost(1.0) //functionscore 对分值影响 .BoostMode(FunctionBoostMode.Replace)//计算boost 模式 ;Replace为替换 .ScoreMode(FunctionScoreMode.Sum) //计算score 模式;Sum为累加
//逻辑区 .Functions(fun=>fun .Weight(w => w.Weight(2).Filter(ft => ft .Term(t => t .Field(fd => fd.cityID).Value(2108))))//匹配cityid +2 .Weight(w => w.Weight(1).Filter(ft => ft .Term(t => t .Field(fd => fd.pvcId).Value(2103))))//匹配pvcid +1 ) ) ) .Size(3000) .Sort(st => st.Descending(SortSpecialField.Score).Descending(dsc=>dsc.priceID)) );
//结果中 cityid=2108,得分=2; pvcid=2103 ,得分=1 ,两者都满足的,得分=3
var result = client.Search<VendorPriceInfo>(s => s
.Query(q => q.QueryString(m => m.Fields(fd=>fd.Field(fdd=>fdd.carName).Field(fdd=>fdd.carGearBox))
.Query("手自一体")
)
)
.From(0)
.Size(15)
);
var result=client.Search<VendorPriceInfo>(s=>s
.Query(q=>q
.Match(m=>m.Field(f=>f.carName)
.Query("尊贵型")
)
)
.From(0)
.Size(15)
);
//多字段匹配
var result1 = client.Search<VendorPriceInfo>(s => s
.Query(q => q
.MultiMatch(m => m.Fields(fd=>fd.Fields(f=>f.carName,f=>f.carGearBox))
.Query("尊贵型")
)
)
.From(0)
.Size(15)
);
var result = client.Search<VendorPriceInfo>(s => s
.Query(q => q.MatchPhrase(m => m.Field(f => f.carName)
.Query("尊贵型")
)
)
.From(0)
.Size(15)
);
const double lat = 39.8694890000;
const double lon = 116.4206470000;
const double distance = 2000.0;
//1
var result = client.Search<VendorPriceInfo>(s => s
.Query(q => q
.Bool(b => b.Must(m => m
.GeoDistance(gd => gd
.Location(lat, lon)
.Distance(distance, DistanceUnit.Meters)
.Field(fd => fd.Location)
))
)
)
.From(0)
.Size(15)
);
//2
var location = new GeoLocation(lat, lon);
var distancei = new Distance(distance, DistanceUnit.Meters);
var result1 = client.Search<VendorPriceInfo>(s => s
.Query(q => q
.Bool(b => b.Must(m => m
.Exists(e => e.Field(fd => fd.Location))
)
)
&&
q.GeoDistance(gd => gd
.Location(location)
.Distance(distancei)
.Field(fd => fd.Location)
)
)
.From(0)
.Size(15)
);
//3
var result2 = client.Search<VendorPriceInfo>(s => s
.Query(q => q
.Bool(b=>b
.Must(m=>m.MatchAll())
.Filter(f=>f
.GeoDistance(g => g
.Name("named_query")
.Field(p => p.Location)
.DistanceType(GeoDistanceType.Arc)
.Location(lat,lon)
.Distance("2000.0m")
)
)
)
)
.From(0)
.Size(15)
);
var result = client.Search<VendorPriceInfo>(s => s
.From(0)
.Size(15)
.Aggregations(ag=>ag
.ValueCount("Count", vc => vc.Field(fd => fd.vendorPrice))//总数
.Sum("vendorPrice_Sum", su => su.Field(fd => fd.vendorPrice))//求和
.Max("vendorPrice_Max", m => m.Field(fd => fd.vendorPrice))//最大值
.Min("vendorPrice_Min", m => m.Field(fd => fd.vendorPrice))//最小值
.Average("vendorPrice_Avg", avg => avg.Field(fd => fd.vendorPrice))//平均值
.Terms("vendorID_group", t => t.Field(fd => fd.vendorID).Size(100))//分组
)
);
//每个经销商 的平均报价
var result = client.Search<VendorPriceInfo>(s => s
.Size(0)
.Aggregations(ag => ag
.Terms("vendorID_group", t => t
.Field(fd => fd.vendorID)
.Size(100)
.Aggregations(agg => agg.Average("vendorID_Price_Avg", av => av.Field(fd => fd.vendorPrice)))
)//分组
.Cardinality("vendorID_group_count", dy => dy.Field(fd => fd.vendorID))//分组数量
.ValueCount("Count", c => c.Field(fd => fd.vendorID))//总记录数
)
);
//每个经销商下 每个品牌 的平均报价
var result = client.Search<VendorPriceInfo>(s => s
.Size(0)
.Aggregations(ag => ag
.Terms("vendorID_group", //vendorID 分组
t => t.Field(fd => fd.vendorID)
.Size(100)
.Aggregations(agg => agg
.Terms("vendorID_cbID_group", //cbID分组
tt => tt.Field(fd => fd.cbID)
.Size(50)
.Aggregations(aggg => aggg
.Average("vendorID_cbID_Price_Avg", av => av.Field(fd => fd.vendorPrice))//Price avg
.Max("vendorID_cbID_Price_Max", m => m.Field(fd => fd.vendorPrice))//Price max
.Min("vendorID_cbID_Price_Min", m => m.Field(fd => fd.vendorPrice))//Price min
.ValueCount("vendorID_cbID_Count", m => m.Field(fd => fd.cbID))//该经销商对该品牌 报价数 count
)
)
.Cardinality("vendorID_cbID_group_count", dy => dy.Field(fd => fd.cbID))//分组数量
.ValueCount("vendorID_Count", c => c.Field(fd => fd.vendorID))//该经销商的报价数
)
)
.Cardinality("vendorID_group_count",dy=>dy.Field(fd=>fd.vendorID))//分组数量
.ValueCount("Count",c=>c.Field(fd=>fd.priceID))//总记录数
) //分组
);
(转)Elasticsearch .net client NEST使用说明 2.x
标签:ica scan 响应 equals images 排序 pat ring ges
原文地址:http://www.cnblogs.com/ywcz060/p/6028789.html