在 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"
}
}
]
}
}
我们可以参考文章 “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"
}
}
}