在 Elasticsearch 中,经常会遇到类似数据的不同索引具有不同字段名称的情况。 例如,一个索引可能使用字段名 level 来表示日志级别,而另一个索引可能使用 log_level 来达到相同目的。 出现这种不一致的原因有多种,例如不同的团队使用不同的命名约定、不断发展的数据模型或集成来自不同来源的数据。
跨两个索引搜索日志级别
要在 loglevel_test1 和 loglevel_test2 索引中搜索日志级别为 “info” 的所有文档,考虑到不同的字段名称,你可以按如下方式构建查询:
PUT loglevel_test1/_doc/1
{"level":"This is a very useful info in test1"
}DELETE loglevel_test2
PUT loglevel_test2/_doc/1
{"log_level":"This is a very useful info in test2"
}GET loglevel_test1,loglevel_test2/_search?filter_path=**.hits
{"query": {"bool": {"should": [{"term": {"level": "info"}},{"term": {"log_level": "info"}}],"minimum_should_match": 1}}
}
此查询检查 loglevel_test1 中的 level 字段和 loglevel_test2 中的 log_level 字段的值 “info”。 在 bool 查询中使用 should 子句可以灵活地匹配任一条件。 minimum_should_match 参数确保文档匹配时至少有一个条件为真,从而从两个索引返回所有相关文档。
上述查询的结果为:
{"hits": {"hits": [{"_index": "loglevel_test2","_id": "1","_score": 0.2876821,"_source": {"log_level": "This is a very useful info in test2"}},{"_index": "loglevel_test1","_id": "1","_score": 0.12343237,"_source": {"level": "This is a very useful info in test1"}}]}
}
使用 alias 来完成
我们可以参考文章 “Elasticsearch : alias 数据类型”。在索引中,我们可以为 loglevel_test2 定义如下的 alias:
PUT loglevel_test2/_mapping
{"properties": {"level": {"type": "alias","path": "log_level"}}
}
这样 level 也就是 log_level 的别名。我们再次使用如下的命令来进行搜索:
GET loglevel_test1,loglevel_test2/_search?filter_path=**.hits
{"query": {"match": {"level": "info"}}
}
上面搜索的结果是:
{"hits": {"hits": [{"_index": "loglevel_test1","_id": "1","_score": 0.2876821,"_source": {"level": "This is a very useful info in test1"}},{"_index": "loglevel_test2","_id": "1","_score": 0.2876821,"_source": {"log_level": "This is a very useful info in test2"}}]}
}
当然上面的搜索索引名称也有一大串。在使用的时候并不方便。我们可以再次使用如下的技巧来进行精简:
GET loglevel_test*/_search?filter_path=**.hits
{"query": {"match": {"level": "info"}}
}