首页 > 解决方案 > 在 ElasticSearch 中搜索“对象”字段的整个文本

问题描述

我有一个 ElasticSearch 索引,它有一个object存储一些非常动态的 JSON 的属性。我想对该 JSON 字段进行全文搜索。如何索引此字段,以便我可以查看某个单词是否出现在 JSON 中的任何位置,而无需提前知道它将出现的确切键?比如,有没有办法只索引 JSON 属性的所有叶节点?顺便说一句,我在 ElasticSearch 6.8 上,所以我没有flattenedfield,我认为它可以做到这一点。

索引定义

PUT /test?include_type_name=true
{
  "settings": {"number_of_shards": 1, "number_of_replicas": 1},
  "mappings": {
    "_doc": {
      "_source": {"enabled": "true"},
      "properties": {
        "content": {
          "type": "object",
          "enabled": "true"
        }
      }
    }
  }
}

文档插入

PUT /test/_doc/1
{
  "content": {
    "a": {
      "b": {
        "text": "42"
      }
    }
  }
}

询问

GET /test/_search
{
  "query": {
    "match": {
      "content": "42"
    }
  }
}

回复:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}

标签: elasticsearch

解决方案


你是对的,flattened字段类型就是你需要的。但在升级之前,您可以使用动态模板来完成。在下面的映射中,我们匹配content对象字段中的任何字符串字段,text并将其值复制到另一个名为content_text我们将能够搜索的字段中:

PUT /test
{
  "mappings": {
    "dynamic_templates": [
      {
        "full_name": {
          "match_mapping_type": "string",
          "path_match": "content.*",
          "mapping": {
            "type": "text",
            "copy_to": "content_text"
          }
        }
      }
    ],
    "properties": {
      "content_text": {
        "type": "text"
      },
      "content": {
        "type": "object",
        "enabled": "true"
      }
    }
  }
}

您的示例文件:

PUT /test/_doc/1
{
  "content": {
    "a": {
      "b": {
        "text": "42"
      }
    }
  }
}

现在您可以在该新字段上进行搜索,就好像您在该字段内的任何字段上进行搜索一样content

GET /test/_search
{
  "query": {
    "match": {
      "content_text": "42"
    }
  }
}

推荐阅读