curl命令
-XGET一种请求方法
-d 标识以post形式传入参数 ,写在请求正文里面
?pretty=true 以格式的形式显示结果
curl -XGET http://localhost:9200/_cluster/health?pretty --查询elasticsearch的健康信息
curl -XGET http://localhost:9200/ --查询实例的相关信息
curl -XGET http://localhost:9200/_cluster/nodes/ --得到集群中节点的相关信息
curl -XPOST http://localhost:9200/_cluster/nodes/_shutdown --关闭整个集群
curl -XPOST http://localhost:9200/_cluster/nodes/aaaa/_shutdown --关闭集群中指定节点
curl -XPOST http://localhost:9200/lishuai --创建名为lishuai的索引
curl -XDELETE http://localhost:9200/lishuai --删除名为lishuai的索引
curl http://10.10.110.160:9200/benlaitest/_analyze?analyzer=standard -d 我爱你中国
postman执行请求API:
http://10.10.110.160:9200/_cat/indices?v -- Get请求 查看有多少索引
http://10.10.110.160:9200/benlaitest/_analyze?analyzer=standard --查看分词结果
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "爱",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "北",
"start_offset": 2,
"end_offset": 3,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "京",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 3
},
{
"token": "天",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 4
},
{
"token": "安",
"start_offset": 5,
"end_offset": 6,
"type": "<IDEOGRAPHIC>",
"position": 5
},
{
"token": "门",
"start_offset": 6,
"end_offset": 7,
"type": "<IDEOGRAPHIC>",
"position": 6
}
]
}
一 DSL查询命令 -基本查询
- term 匹配指定的文档单元(匹配的是分词后的词条,假如川普分词后为 川和普,那么term匹配川普是无结果的,要用term匹配'川'或者'普'),1 至少匹配1个 2匹配两个:
{"terms":{"tag":["a","b"],"mininmum":1}}
- match 根据不同的字段选择合适的分析器,一个很智能的查询器,可以通过指定他的参数来控制匹配行文 operator 控制关联的查询条件 and或者or:
{"query":{match{"title":{"query":"a b }c","operation":"and"}}}
- multi_match 与match查询类似,不同的是它可以作用在多个字段上:
{"query":{"multi_match":{"query":"a v b","fields":["title","content"]}}}
- query_string 查询 支持lucene的查询语法:
{"query":{"query_string":{"query":"titlename:你好^10 +titlename:哈哈","default_field":"titlename"}}} {"query":{"query_string":{"query":"你好 中国","fields":["title","name"],"use_dis_max":true}}}
- range查询 只针对单个字段
{"query":{"range":{"year":{"from":1700,"to":1900}}}}
bool查询,复合查询,可以将无限数目的查询封装在一起
{"query":{"bool":{"must":{"term":{"title":"中国"}},"should":{"term":{"name":"帅"}}}}}
其他查询方式:
- boosting查询 两个查询封装一起的查询
- constant_score 恒定分值查询
- indices 针对多个索引进行查询
- custom_filter_score custom_boost_factor custom_score
- ids
{ "query": { "ids": { "type": "product", "values": [ "0001-2020774", "0001-2020775" ] } } }
- prefix 前缀查询
- 模糊查询
- fuzzy 查询 相似度查询,消耗cpu
- fuzzy_like_zhis 基于模糊串
- fuzzy_like_zhis_field
- more_like_this
- mroe_like_this_field
- match_all 匹配所有文档
- wildcard 查询 通配符查询
二 DSL查询命令 - 范围查询和排序
1 index/product/_search 查询6到11块的商品
{
"query": {
"range": {
"price": {
"gte": "6",
"lte": "11"
}
}
}
}
2 查询0-11块之间的商品,先按照相关性得分降序排列,然后按照价格升序
{
"query": {
"range": {
"price": {
"gte": "0",
"lte": "11"
}
}
},
"sort": [
{
"_score": "desc"
},
{
"price": "asc"
}
]
}
结果:
三:DSL查询命令 - 过滤器
1)过滤器会先执行查询,然后再对查询文档进行过滤
{
"query": {
"field": {
"title": "中国"
},
"filter": {
"term": {
"year": 1949
}
}
}
}
但是先执行过滤,然后对过滤结果进行查询。效率更高:
{
"filter": {
"range": {
"year": {
"from": 1700,
"to": 1900
}
}
}
}
{
"query": {
"filtered": {
"field": {
"title": "中国"
},
"filter": {
"term": {
"year": 1949
}
}
}
}
}
2)exists过滤器 只过滤有指定字段的文档 相反的 missing
3)script 脚本过滤 ,过滤得到100年以前的文档:
{
"filter": {
"script": {
"script": "now - doc['year'].value>100",
"params": {
"now": 2016
}
}
}
}
四:DSL查询命令 - 聚合
AGGS
1)针对性别进行分组:
{
"size": 0,
"aggs": {
"agg_sex": {
"terms": {
"field": "gender"
}
}
}
}
结果:
{
"took": 24,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 6,
"max_score": 0,
"hits": [
]
},
"aggregations": {
"agg_sex": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 1,
"key_as_string": "true",
"doc_count": 4
},
{
"key": 0,
"key_as_string": "false",
"doc_count": 2
}
]
}
}
}
2)得到最大价格:
{
"size": 0,
"aggs": {
"agg_price": {
"max": {
"field": "price"
}
}
}
}
结果:
{
"took": 16,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 6,
"max_score": 0,
"hits": [
]
},
"aggregations": {
"agg_price": {
"value": 20.36
}
}
}
另外还有: min,max,sum,avg range,postfilter解决了仅仅过滤搜索结果,但是并不影响聚合结果
五:DSL查询命令 - 统计
faceting
1)query统计:
{"query":{"match_all":{}},"facets":{"my_query_facet":{"query":{"term":{"tags":"person"}}}}}
2)filter统计:my_filter_facet
3)terms统计:返回指定字段中使用最多的词项
4)range统计 :ranges_facet_result 统计指定范围的文档数。选取不同的字段进行数据聚合计算,使用 key_field和key_value 前者指定应该对哪个字段取值检查是否属于指定范围,后者指明
应该对那些字段进行聚合计算
5)statistical统计:是的我们可以对一个数值型字段计算统计,得到个数综合平方和均值最小值最大值
{"query":{"match_all":{}},"facets":{"statistical_test":{"statistical":{"field":"price"}}}}
6)terms_stats 统计,过滤统计结果:facet_filter
六:mapping嵌套
mapping:{
"mappings": {
"test": {
"properties": {
"productname": {
"type": "string"
},
"category": {
"type": "nested",
"properties": {
"category1Sysno": {
"type": "string",
"index": "not_analyzed"
},
"category2Sysno": {
"type": "string",
"index": "not_analyzed"
},
"category3Sysno": {
"type": "string",
"index": "not_analyzed"
},
"category1Souce": {
"type": "int",
"index": "not_analyzed"
},
"category2Souce": {
"type": "int",
"index": "not_analyzed"
},
"category3Souce": {
"type": "int",
"index": "not_analyzed"
}
}
}
}
}
}
}
//DSL 查询
{
"query": {
"nested": {
"path": "category",
"query": {
"bool": {
"must": [
{
"term": {
"category.category1Sysno": "1"
}
}
]
}
}
}
}
}
//注意:在嵌套和父子中,不能根据子文档field进行排序;例如此例中根据category.category1Souce对搜索结果进行排序;
//使用对象数组的方式可以排序,排序语句:
"sort": [
{
"category.category1Souce": "asc"
}
七:嵌套聚合
- 查询嵌套文档中onlinecategory.category2Sysno为11的且先按照onlinecategory.category3Souce升序在按照price降序排列
- 增加 nested_path 和 nested_filter 重复查询条件的原因是:排序发生在查询执行之后 查询条件限定了只查询category2Sysno为11的文档,如果排序子句中不加入此条件,排序就是基于所有文档的onlinecategory.category3Souce来排序的,而不仅仅是"onlinecategory.category2Sysno": 11的文档【但是此处是不需要加的因为加不加都是正确的,只做演示,基于范围的筛选加了才有意义】
- 可以聚合嵌套的文档,同时聚合本身也可以嵌套很多层
聚合结果排序(聚合后,按照每个桶的_count数量排序)
{ "query": { "nested": { "path": "onlinecategory", "query": { "term": { "onlinecategory.category2Sysno": "11" } } } }, "sort": [ { "onlinecategory.category3Souce": { "order": "desc", "mode": "max", "nested_path": "onlinecategory", "nested_filter": { "term": { "onlinecategory.category2Sysno": 11 } } } }, { "price": { "order": "asc" } } ], "aggs": { "size_onlinecategory": { "nested": { "path": "onlinecategory" }, "aggs": { "size_category3Sysno": { "terms": { "field": "onlinecategory.category3Sysno", "order": { "_count": "desc" } } }, "size_category2Sysno": { "terms": { "field": "onlinecategory.category2Sysno" } } } } } }
嵌套索引创建: 定义mapping:
[ElasticsearchType(Name = "product")] public class NestProduct { [String(Store = true, Index = FieldIndexOption.NotAnalyzed)] public string Id { get; set; } [String(Store = true, Index = FieldIndexOption.Analyzed)] public string Name { get; set; } [String(Store = true, Index = FieldIndexOption.NotAnalyzed)] public string Stock { get; set; } [String(Store = true, Index = FieldIndexOption.NotAnalyzed)] public string Price { get; set; } [Nested(Name ="onlinecategory")] //Path ="onlinecategory" 也可以 public List<NestCategory> Categorys { get; set; } } [ElasticsearchType(Name = "category")] public class NestCategory { [String(Store = true, Index = FieldIndexOption.Analyzed)] public string Category1Name { get; set; } [String(Store = true, Index = FieldIndexOption.NotAnalyzed)] public string Category1Sysno { get; set; } [String(Store = true, Index = FieldIndexOption.Analyzed)] public string Category2Name { get; set; } [String(Store = true, Index = FieldIndexOption.NotAnalyzed)] public string Category2Sysno { get; set; } [String(Store = true, Index = FieldIndexOption.Analyzed)] public string Category3Name { get; set; } [String(Store = true, Index = FieldIndexOption.NotAnalyzed)] public string Category3Sysno { get; set; } }
创建索引:
var decriptior = new CreateIndexDescriptor("nestproduct").Mappings(map => map.Map<NestProduct>(m => m.AutoMap())); var response = ElasticSearchCommon.GetInstance().GetElasticClient().CreateIndex(decriptior);
嵌套的查询,排序和聚合:
/// <summary> /// 嵌套查询 /// </summary> /// <returns></returns> public List<NestProduct> NestedSearch() { //搜索包含车厘子的且中类为12 小类为121的商品 //嵌套查询条件 List<QueryContainer> qc = new List<QueryContainer>(); qc.Add(new TermQuery { Field = "onlinecategory.category2Sysno", Value = "11" }); //qc.Add(new TermQuery { Field = "onlinecategory.category3Sysno", Value = "121" }); NestedQuery nestq = new NestedQuery { Path= "onlinecategory", Query=new BoolQuery() { Must= qc} }; //非嵌套查询条件 MatchPhraseQuery matchPhraseQuery = new MatchPhraseQuery { Field = "name", Query = "车厘子" }; //组合上面的查询条件 List<QueryContainer> qcall = new List<QueryContainer>(); qcall.Add(nestq); qcall.Add(matchPhraseQuery); BoolQuery bq = new BoolQuery() { Must = qcall }; //使用嵌套字段排序 //1 默认情况下,根文档的分数是这些嵌套文档分数的平均值。可以通过设置 score_mode 参数来控制这个得分策略, //相关策略有 avg (平均值), max (最大值), sum (加和) 和 none (直接返回 1.0 常数值分数)。 //2 考虑将查询条件作为 NestedFilter 子句 https://www.elastic.co/guide/cn/elasticsearch/guide/current/nested-sorting.html List<ISort> sortlist = new List<ISort>() ; sortlist.Add(new SortField() { Field = "onlinecategory.category3Souce", NestedPath= "onlinecategory",Mode= SortMode.Min, NestedFilter= bq, Order = SortOrder.Ascending }); sortlist.Add(new SortField() { Field = "price", Order = SortOrder.Ascending }); //聚合 //Dictionary<string, AggregationContainer> container = new Dictionary<string, AggregationContainer>(); //container.Add //聚合嵌套 NestedAggregation nestedAgg = new NestedAggregation("agg_onlinecategory") { Path = "onlinecategory", Aggregations = new TermsAggregation("agg_oc3sysno") { Field = "onlinecategory.category3Sysno", Order = new List<TermsOrder>() { new TermsOrder() { Key = "_count", Order = SortOrder.Descending } } } }; //执行搜索 SearchRequest<NestProduct> searchRequest = new SearchRequest<NestProduct>("nestproduct", "product") { From = 0, Size = 100, Query = bq, //Sort= sortlist Aggregations= nestedAgg }; var client = ElasticSearchCommon.GetInstance().GetElasticClient(); var response = client.Search<NestProduct>(searchRequest); //结果处理 List<NestProduct> prolist = new List<NestProduct>(); foreach (var i in response.Hits) { prolist.Add(i.Source); } //获取聚合信息 List<NestCategory> nestcat = new List<NestCategory>(); //获取指定的桶对象 var buck = response.Aggs.Aggregations["agg_onlinecategory"] as SingleBucketAggregate; var termbuck = buck.Aggregations["agg_oc3sysno"] as BucketAggregate; foreach (KeyedBucket b in termbuck.Items) { nestcat.Add(new NestCategory() { Category3Sysno = b.Key }); } return prolist; }
八: mapping父子
//创建父子类型mapping,在子类型上指定父类型是谁
http://192.168.60.61:29200/qtorder
{
"mappings": {
"order": {
"properties": {
"sysno": {
"type": "string",
"index": "not_analyzed"
},
"uid": {
"type": "string",
"index": "not_analyzed"
},
"createTime": {
"type": "date",
"index": "not_analyzed"
}
}
},
"orderItem": {
"_parent": { //此处只需要指定父类型是谁即可
"type": "order"
},
"properties": {
"productname": {
"type": "string",
"index": "analyzed"
},
"productid": {
"type": "string",
"index": "not_analyzed"
},
"ordersysno": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
插入嵌套关系的数据,例如一个订单里面有3个商品,那么对象关系是一个订单对象里包含了一个商品列表对象,列表里有3个商品数据;而我们需要创建一个订单类型索引数据为父文档,三个产品类型索引数据为子文档
public class objmanger
{
//sysno为订单号,指定默认id为订单号(唯一的)
public static List<order> CreateOrder()
{
List<order> orders = new List<order>();
orders.Add(new order { id="1001", createTime="2016-07-01", sysno="1001", uid="u1" });
orders.Add(new order { id = "1002", createTime = "2016-07-02", sysno = "1002", uid = "u2" });
return orders;
}
//ordersysno为订单号,对应order对象里的sysno和id
public static List<orderItem> CreateOrderItem()
{
List<orderItem> items = new List<orderItem>();
items.Add(new orderItem { ordersysno = "1001", productid = "p0011", productname = "产品11" });
items.Add(new orderItem { ordersysno = "1001", productid = "p0012", productname = "产品12" });
items.Add(new orderItem { ordersysno = "1001", productid = "p0013", productname = "产品13" });
items.Add(new orderItem { ordersysno = "1002", productid = "p0014", productname = "产品14" });
items.Add(new orderItem { ordersysno = "1002", productid = "p0015", productname = "产品15" });
items.Add(new orderItem { ordersysno = "1002", productid = "p0016", productname = "产品16" });
return items;
}
}
插入数据
public static void createparent()
{
var client = ElasticSearchCommon.GetInstance().GetElasticClient();
var des = new BulkDescriptor().Index("qtorder");
var orders = objmanger.CreateOrder();
foreach (var i in orders)
{
des.Index<order>(o => o.Document(i));
}
var response = client.Bulk(des);
}
public static void createchild()
{
var client = ElasticSearchCommon.GetInstance().GetElasticClient();
var des = new BulkDescriptor().Index("qtorder");
var items = objmanger.CreateOrderItem();
foreach (var i in items)
{
des.Type("orderItem").Index<orderItem>(o => o.Document(i).Parent(i.ordersysno));
}
var response2 = client.Bulk(des);
//foreach(var i in items)
//{
// var request = new IndexRequest<orderItem>("qtorder", "orderItem", i.productid);
// request.Document = i;
// request.Parent=i.orderid;
// var respon= client.Index(request);
//}
}
查询
查询子文档商品名称包含 “产品” 的父文档订单信息(只返回父文档信息):
post http://192.168.60.61:29200/qtorder/order/_search
{
"query":{
"has_child": {
"type": "orderItem",
"query": {
"match": {
"productname": "产品"
}
}
} }
}
返回结果:
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "qtorder",
"_type": "order",
"_id": "1001",
"_score": 1,
"_source": {
"id": "1001",
"ordersysno": "1001",
"uid": "u1",
"createTime": "2016-07-01"
}
},
{
"_index": "qtorder",
"_type": "order",
"_id": "1002",
"_score": 1,
"_source": {
"id": "1002",
"ordersysno": "1002",
"uid": "u2",
"createTime": "2016-07-02"
}
}
]
}
}
查询用户u1买过的所有商品,(根据父文档条件查询子文档信息,只返回子文档信息),注意,下面orderid就是上面的ordersysno,忘改:
nest代码
/// <summary>
/// 嵌套查询
/// 使用嵌套在一些情况下不用聚合就能得到结果
/// </summary>
public static void query()
{
var client = ElasticSearchCommon.GetInstance().GetElasticClient();
//TypeName [] ts = new TypeName[] { "order"};
var result = client.Search<order>(s => s
.Index("qtorder")
.Type("order")
//.Query(q => q.Term("uid", "u1"))
//.Query(q => q.HasChild<orderItem>(c => c.Type("orderItem").Query(cq => cq.Term("productid", "p0011"))))//查询买过商品p0011的 订单
.Query(q => q.HasChild<orderItem>(c => c.Type("orderItem").Query(cq => cq.Match(o => o.Name("productname").Query("苹果")))))//查询子文档商品名称包含苹果的父文档信息
);
IEnumerable<order> ss = result.Documents;
}
//多个文档类型查询
public static void query()
{
var client = ElasticSearchCommon.GetInstance().GetElasticClient();
TypeName[] ts = new TypeName[] { "order", "giftOrder" };
var result = client.Search<order>(s => s
.Index("qtorder")
.Type(ts)
//.Query(q => q.HasChild<orderItem>(c => c.Type("orderItem").Query(cq => cq.Term("productid", "p0011"))))//查询买过商品p0011的 订单
.Query(q => q.HasChild<orderItem>(c => c
.Type("orderItem").Query(cq => cq.Match(o => o.Name("productname").Query("产品")))
.Type("giftOrderItem").Query(cq => cq.Match(o => o.Name("productname").Query("产品")))
))//查询子文档商品名称包含苹果的父文档信息
);
IEnumerable<order> ss = result.Documents;
}
es 支持文档嵌套和父子文档,文档嵌套式内容嵌套,一个大文档里面包含多个小文档;父子文档是指为两个独立的文档类型建立父子关联关系;
父子文档查询时也支持多个类型查询
文档id:同一文档类型下,文档id不能重复,同一索引不同类型下的两个文档id可以是相同的
//查询订单内容包含“礼金”,且用户是2340458的订单号,父子条件同时查询
http://192.168.60.61:29200/order20160801/giftOrder/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"uid": "2340458"
}
},
{
"has_child": {
"type": "giftOrderProduct",
"query": {
"term": {
"productName": "礼金"
}
}
}
}
]
}
}
}
//查询根据多个子类型信息,已经父类型信息,查询多个父类型。查询用户23130购买过包含“电子“的商品的订单(包含普通订单和礼品卡订单)
http://192.168.60.61:29200/order20160801/giftOrder,order/_search
{
"from":0,
"size":100,
"query": {
"bool":{"should":[
{"bool":{"must":[{"term": {"uid": "23130"}}, { "has_child": {"type": "giftOrderProduct","query": {"term": {"productName": "电子"}}}}]}},
{"bool":{"must":[{"term": {"uid": "23130"}}, { "has_child": {"type": "orderProduct","query": {"term": {"productName": "电子"}}}}]}}
]}
}
}