全文检索场景在实际项目中,无界搜索具体查询某一个字段对于客户来说是不确定的,但是实际数据中需要检索的字段非常多。
在使用elasticsearch时遇见了这样的需求:es聚合指定字段时聚合的结果里面只显示聚合的字段。但是在做报表时,我们发现一个问题:如果我们对员工进行聚合,但是我们还希望查看当前员工所在的班组,部门等信息。这时如果查询es两次,对于效率来说是不好的。
这样,我们在设计的时候就需要将更多的字段合并成一个字段,这样查询的时候,开发人员只需要查询指定的那个字段就可以了,中间实现过程很简单,但是更多的会涉及到性能优化和分词优化。使用的步骤:
1、创建mapping
-
PUT my_index
-
{
-
"mappings": {
-
"my_type": {
-
"properties": {
-
"first_name": {
-
"type": "keyword",
-
"copy_to": "full_name"
-
},
-
"last_name": {
-
"type": "keyword",
-
"copy_to": "full_name"
-
},
-
"full_name": {
-
"type": "text",
-
"fielddata": true
-
}
-
}
-
}
-
}
-
}
2、插入数据
-
PUT my_index/my_type/1
-
{
-
"first_name": "John",
-
"last_name": "Smith"
-
}
3、查询校验
-
GET my_index/_search
-
{
-
"query": {
-
"match": {
-
"full_name": {
-
"query": "John Smith",
-
"operator": "and"
-
}
-
}
-
}
-
}
4、结果展示
-
{
-
"took": 0,
-
"timed_out": false,
-
"_shards": {
-
"total": 5,
-
"successful": 5,
-
"failed": 0
-
},
-
"hits": {
-
"total": 1,
-
"max_score": 0.51623213,
-
"hits": [
-
{
-
"_index": "my_index",
-
"_type": "my_type",
-
"_id": "1",
-
"_score": 0.51623213,
-
"_source": {
-
"first_name": "John",
-
"last_name": "Smith"
-
}
-
}
-
]
-
}
-
}
5、聚合查询校验
-
{
-
"query": {
-
},"aggs": {
-
"1": {
-
"terms": {
-
"field": "full_name",
-
"size": 10
-
}
-
}
-
}
-
}
6、查询结果
-
{
-
"took": 0,
-
"timed_out": false,
-
"_shards": {
-
"total": 5,
-
"successful": 5,
-
"failed": 0
-
},
-
"hits": {
-
"total": 1,
-
"max_score": 1,
-
"hits": [
-
{
-
"_index": "baobiaoceshi4",
-
"_type": "my_type",
-
"_id": "1",
-
"_score": 1,
-
"_source": {
-
"first_name": "John",
-
"last_name": "Smith"
-
}
-
}
-
]
-
},
-
"aggregations": {
-
"1": {
-
"doc_count_error_upper_bound": 0,
-
"sum_other_doc_count": 0,
-
"buckets": [
-
{
-
"key": "john",
-
"doc_count": 1
-
},
-
{
-
"key": "smith",
-
"doc_count": 1
-
}
-
]
-
}
-
}
-
}
注意有这几个问题:
1、我们copy_to指向的字段字段类型要为:text
2、text类型字段如果希望进行聚合,设置属性:"fielddata": true
3、copy_to指向的字段不会在head插件查看时显示,但是能通过查询语句作为条件
总结:通过这种方式对我们的结果进行聚合,能够满足一次查询聚合多个字段。
sapv博客之家,欢迎交流!