Elasticsearch-搜索并获取数据
在group中搜索elasticsearch
curl -XGET "localhost:9200/get-together/group/_search?\
> q=elasticsearch\> &fields=name,location\> &size=1\> $pretty"
URL指出在何处进行查询:在get-together索引的group类型中
URI参数给出了搜索的细节:发现包含“elasticsearch”的文档,但是只返回排名靠前结果的name和location字段
1.在哪里搜索
可以告诉ES在特定的类型和特定索引中进行查询,但是也可以在同一个索引的多个字段中搜索、在多个索引中搜索或是在所有的索引中搜索。
(1).在多个类型中搜索,使用逗号分隔的列表。如:同时在group和event类型中搜索
FengZhendeMacBook-Pro:bin FengZhen$ curl "localhost:9200/get-together/group,event/_search?q=elasticsearch&pretty"
(2).通过向索引URL的_search端点发送请求,可以在某个索引的多个类型中搜索
FengZhendeMacBook-Pro:bin FengZhen$ curl "localhost:9200/get-together/_search?q=elasticsearch&pretty"
(3).和类型类似,为了在多个索引中搜索,用逗号分隔它们
FengZhendeMacBook-Pro:bin FengZhen$ curl "localhost:9200/get-together,other_index/_search?q=elasticsearch&pretty"
如果事先没有创建other-index,这个特定的请求将会失败。为了忽略这种问题,可以像pretty旗标那样添加ignore_unavailable旗标。
FengZhendeMacBook-Pro:bin FengZhen$ curl "localhost:9200/get-together,other_index/_search?q=elasticsearch&ignore_unavailable&pretty"
(4).在所有的索引中搜索,彻底省略索引的名称
FengZhendeMacBook-Pro:bin FengZhen$ curl "localhost:9200/_search?q=elasticsearch&ignore_unavailable&pretty"
如果需要在所有索引内搜索,也可以使用名为_all的占位符作为索引的名称。当需要在全部索引中的同一个单独类型中进行搜索时,这一点就派上用场了,如
FengZhendeMacBook-Pro:bin FengZhen$ curl "localhost:9200/_all/event/_search?q=elasticsearch&ignore_unavailable&pretty"
2.回复的内容
除了和搜索条件匹配的文档,搜索答复还包含其他有价值的信息,用于检验搜索的性能或结果的相关性。
FengZhendeMacBook-Pro:bin FengZhen$ curl "localhost:9200/get-together/group/_search?q=Test&ignore_unavailable&pretty"
{"took" : 24,"timed_out" : false,"_shards": {"total" : 5,"successful" : 5,"failed" : 0},"hits": {"total" : 1,"max_score" : 0.15342641,"hits": [ {"_index" : "get-together","_type" : "group","_id" : "1","_score" : 0.15342641,"_source": {"name" : "ES Test","organizer" : "Feng"}
} ]
}
}
解析返回结果
"took" : 24,
"timed_out" : false,
请求耗时多久,以及它是否超时
"total" : 5,
"successful" : 5,
"failed" : 0
查询了多少分片
"total" : 1,
"max_score" : 0.15342641,
"hits" : [ {
所有匹配文档的统计数据
"hits" : [ {
"_index" : "get-together",
"_type" : "group",
"_id" : "1",
"_score" : 0.15342641,
"_source" : {
"name" : "ES Test",
"organizer" : "Feng"
}
} ]
结果数组
(1)时间
"took" : 24,"timed_out" : false,
其中took字段告诉ES花了多久处理请求,时间单位是毫秒,而time_out字段表示搜索请求是否超时。默认情况下,搜索永远不会超时,但是可以通过timeout参数来设定限制。如:设置3秒超时
FengZhendeMacBook-Pro:bin FengZhen$ curl "localhost:9200/get-together/group/_search?q=Test&ignore_unavailable&pretty&timeout=3s"
如果搜索超时了,timed_out字段的值就是true,而且只能获得超时前所收集的结果
(2).分片
"_shards": {"total" : 5,"successful" : 5,"failed" : 0},
在一个拥有5份分片的索引中搜索,所有的分片都有返回,所以成功(successful)的值是5,而失败(failed)的值是0.
当一个节点宕机而且一份分片无法回复搜索请求时,ES提供正常分片中的结果,并在failed字段中报告不可搜索的分片数量。
(3).命中统计数据
回复的最后一项组成元素是hits,它包含了匹配文档的数组。在数组之前,包含了几项统计信息
"total" : 1,"max_score" : 0.15342641,
将看到匹配文档的总数,而且通过max_score会看到这些匹配文档的最高得分
搜索返回的文档得分,是该文档和给定搜索条件的相关性衡量。得分默认是通过TF-IDF(词频-逆文档频率)算法进行计算的。词频意味着对于搜索的每个词条,其在某篇文档中出现的次数越多则该文档的得分就越高。逆文档频率意味着,如果该词条在整个文档集合中出现在越少的文档中则该文档得分越高,原因是我们会认为词条和这篇文档的相关度更高。如果词条经常在其它文档中出现,他可能是一个常见词,相关性更低。
文档的总数和回复中的文档数量可能不匹配,因为ES默认返回10篇文档,可以使用size参数来修改返回的结果数量。
(4)结果文档
"hits": [ {"_index" : "get-together","_type" : "group","_id" : "1","_score" : 0.15342641,"_source": {"name" : "ES Test","organizer" : "Feng"}
} ]
展示了每个匹配文档所属的索引和类型、它的ID和它的得分,若在查询时没有通过fields指定查询的字段,则会展示_source字段。和_all一样,_source是一个特殊的字段,ES默认在其中存储原始的JSON文档。
指定fields的查询:
curl "localhost:9200/get-together/group/_search?q=Test&fields=name,location&ignore_unavailable&pretty"
"hits": [ {"_index" : "get-together","_type" : "group","_id" : "1","_score" : 0.15342641,"fields": {"name" : [ "ES Test"]
}
} ]
3.如何搜索
ES允许使用JSON格式指定所有的搜索条件。当搜索变得越来越复杂的时候,JSON更容易读写,并且提供了更多的功能。
FengZhendeMacBook-Pro:bin FengZhen$ curl 'localhost:9200/get-together/group/_search?pretty' -d '{"query":{"query_string":{"query":"Test"}
}
}'
运行一个类型为query_string的查询,字符串内容是Test
(1).设置查询的字符串选项
ES默认查询_all字段。如果想在分组的名称里查询,需要指定:
“default_field”:”name”
同样,ES默认返回匹配了任一指定关键词的文档(默认的操作符是OR)。如果希望匹配所有的关键词,需要指定:
“default_operator”:”AND”
修改后的查询:
FengZhendeMacBook-Pro:bin FengZhen$ curl 'localhost:9200/get-together/group/_search?pretty' -d '{"query":{"query_string":{"query":"ES san francisco",
“default_field”:”name”,
“default_operator”:”AND”
}
}
}'
获取同样结果的另一种方法是查询字符串中指定字段和操作符
“query”:”name:ES AND name:san AND name:francisco”
(2).选择合适的查询类型
如果在name字段中查找“Test”一个词,term查询可能更快捷、更直接
FengZhendeMacBook-Pro:bin FengZhen$ curl 'localhost:9200/get-together/group/_search?pretty' -d '{"query":{"term":{"name":"Test"}
}
}'
(3).使用过滤器
如果对得分不感兴趣,可以使用过滤查询来替代。过滤只关心一条结果是否匹配搜索条件,因此,对比相应的查询,过滤查询更为快速而且更容易缓存。
FengZhendeMacBook-Pro:bin FengZhen$ curl 'localhost:9200/get-together/group/_search?pretty' -d '{"query":{
“filtered”:{
“filter”:{"term":{"name":"Test"}
}
}
}
}'
返回的结果和同样词条的查询相同,但是结果没有根据得分来排序(因为所有的结果得分都是1.0)
(4).应用聚集
除了查询和过滤,还可以通过聚集进行各种统计。词条聚集(terms aggregation)。这会展示指定字段中出现的每个词的计数器。
curl 'localhost:9200/get-together/group/_search?pretty' -d '{"aggregations":{"organizers":{"terms":{"field":"organizer"}
}
}
}'
聚集解释:给我一个名为organizers的聚集,类型是terms,并且查找organizers字段
{"took" : 25,"timed_out" : false,"_shards": {"total" : 5,"successful" : 5,"failed" : 0},"hits": {"total" : 2,"max_score" : 1.0,"hits": [ {"_index" : "get-together","_type" : "group","_id" : "2","_score" : 1.0,"_source": {"name" : "Din","organizer" : "DinDin"}
}, {"_index" : "get-together","_type" : "group","_id" : "1","_score" : 1.0,"_source": {"name" : "ES Test","organizer" : "Feng"}
} ]
},"aggregations": {"organizers": {"doc_count_error_upper_bound" : 0,"sum_other_doc_count" : 0,"buckets": [ {"key" : "dindin","doc_count" : 1}, {"key" : "feng","doc_count" : 1} ]
}
}
}
结果表示,”feng”出现了1次,”dindin”出现了一次。
4.通过ID获取文档
为了获取一个具体的文档,必须要知道它所属的索引和类型,以及它的ID。
FengZhendeMacBook-Pro:nacos FengZhen$ curl 'localhost:9200/get-together/group/1?pretty'{"_index" : "get-together","_type" : "group","_id" : "1","_version" : 1,"found" : true,"_source": {"name" : "ES Test","organizer" : "Feng"}
}
回复包括所指定的索引、类型和ID。如果文档存在,会发现found字段的值是true,此外还有其版本和源。如果文档不存在,found为false。
通过ID获得的文档要比搜索更快,所消耗的资源成本也更低。这也是实时完成的:只要一个索引操作完成了,新的文档就可以通过GET API获取。相比之下,搜索时近实时的,因为它们需要等待默认情况下每秒进行一次的刷新操作。