弹性搜索获取错误创建索引

时间:2019-11-27 00:17:43

标签: elasticsearch

我是ES的新手...在线找到了一个教程:

PUT /company
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    },
    "analysis": {
      "analyzer": {
        "analyzer-name": {
          "type": "custom",
          "tokenizer": "keyword",
          "filter": "lowercase"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "age": {
        "type": "integer"
      },
      "experienceInYears": {
        "type": "integer"
      },
      "name": {
        "type": "keyword",
        "analyzer": "analyzer-name"
      }
    }
  }
}

这有什么问题?我收到以下错误:

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "Mapping definition for [name] has unsupported parameters:  [analyzer : analyzer-name]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "Failed to parse mapping [_doc]: Mapping definition for [name] has unsupported parameters:  [analyzer : analyzer-name]",
    "caused_by": {
      "type": "mapper_parsing_exception",
      "reason": "Mapping definition for [name] has unsupported parameters:  [analyzer : analyzer-name]"
    }
  },
  "status": 400
}

我发现现场分析器是引起问题的原因:),但这不是正确的吗?

4 个答案:

答案 0 :(得分:1)

关键字数据类型没有分析器参数,文本数据类型没有。

在文档中为这两种数据类型检出允许的参数:

因此,您的名称属性映射应更改为此。

  ...
  "name": {
    "type": "text",
    "analyzer": "analyzer-name"
  }
  ...

答案 1 :(得分:1)

尽管已经指出了错误的原因,并且还提到了一种避免解决方案的方法,但我只想确保您了解另一种解决问题的方法并了解其优缺点, ES的新手。

索引部分

关键字字段按原样存储,这意味着它不会通过analysis process,因此,您字段中存在的文本将按原样存储在ES的反向索引中,该索引用于搜索ES搜索基于令牌匹配。但是,如果您将字段定义为文本,并且未指定分析器ES默认分析器,则将使用standard analyzer,无论哪种情况,您的文本都将经过我提到的分析阶段,结果标记将是存储在倒排索引中。

搜索部分

现在,字段类型在执行搜索中起着重要作用。请参阅This SO answer for more info。简而言之,搜索查询也经历了分析阶段,该阶段再次取决于各种因素,并生成了将与search tokens相匹配的indexed tokens因此,在决定使用哪种字段和使用哪种分析器之前,务必先了解整个用例。

为您提供另一种解决方案,只需将name字段定义为关键字字段,即可通过将结构更改为以下内容来实现:

"name": {
    "type": "keyword" // notice I removed analyzer section.
  }

答案 2 :(得分:1)

正如其他成员所说:关键字数据类型没有分析器参数。

在我看来,您想为关键字字段类型创建小写的analyzer

为此,您应该创建一个normalizer(用于关键字类型)。

Normalizer

一个工作示例:

使用normalizer创建映射:

PUT /company
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    },
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "filter": [
            "lowercase"
          ],
          "type": "custom"
        }
      },
      "analyzer": {
        "analyzer-name": {
          "type": "custom",
          "tokenizer": "keyword",
          "filter": "lowercase"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "age": {
        "type": "integer"
      },
      "experienceInYears": {
        "type": "integer"
      },
      "name": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "normalizer": "my_normalizer"
          }
        }
      }
    }
  }
}

我们发布一个文档:

POST company/_doc/1
{
  "name":"WwW.CoM"
}

如您所见,name的值由大小写字母组合而成。

如果没有normalizer,您将无法寻找www.com,因为keyword类型会寻找完全匹配。

让我们执行搜索查询:

GET company/_search
{
  "query": {
    "term": {
      "name.keyword": {
        "value": "www.com"
      }
    }
  }
}

结果:

{
 "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "company",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "WwW.CoM"
        }
      }
    ]
  }
}

我希望这是您想要实现的目标。

答案 3 :(得分:1)

关键字数据类型不支持分析器参数。

PUT /company
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    },
    "analysis": {
      "analyzer": {
        "analyzer-name": {
          "type": "custom",
          "tokenizer": "keyword",
          "filter": "lowercase"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "age": {
        "type": "integer"
      },
      "experienceInYears": {
        "type": "integer"
      },
      "name": {
        "type": "text",
        "analyzer": "analyzer-name"
      }
    }
  }
}