首页 > 解决方案 > Elasticsearch 分析器在创建时工作抛出 Springdata 但在直接从 Postman/curl 创建时失败

问题描述

目标:创建旨在加载 1000 万个简单文档的 Elasticsearch 索引。每个文档基本上都是“Elastisearch id”、“some company id”和“name”。提供 search-as-suer-type 功能。

我可以直接从 Postman(curl 或任何其他不依赖 Spring Data 的工具)或在 Spring 引导初始化期间成功创建索引和分析器。然而,当我尝试使用分析器时,它似乎被直接从 Postman 创建的分析器忽略了。

所以我的主要问题是:当我尝试直接发布 json 字符串时,Springdata 是否添加了一些我缺少的设置?第二个问题是:是否有某种方式可以使 Springdata 打印自动生成和执行的命令(与 Hibernate 类似的方法允许您查看打印的命令)?如果是这样,我可以直观地调试并检查有什么不同。

这是从 Springboot/Spring-Data 创建 Index 和 Analyzer 的方式。

启动的主要方法

@EnableElasticsearchRepositories
@SpringBootApplication
public class SearchApplication {

    public static void main(String[] args) {
        SpringApplication.run(SearchApplication.class, args);
    }

}

我的模型

@Document(indexName = "correntistas")
@Setting(settingPath = "data/es-config/elastic-setting.json")
@Getter
@Setter
public class Correntista {
    @Id
    private String id;
    private String conta;
    private String sobrenome;

    @Field(type = FieldType.Text, analyzer = "autocomplete_index", searchAnalyzer = "autocomplete_search")
    private String nome;
}

src/main/resources/data/es-config/elastic-setting.json *** 注意这与我从 POSTMAN 发布的设置完全相同

{
  "analysis": {
    "filter": {
      "autocomplete_filter": {
        "type": "edge_ngram",
        "min_gram": 1,
        "max_gram": 20
      }
    },
    "analyzer": {
      "autocomplete_search": {
        "type": "custom",
        "tokenizer": "standard",
        "filter": [
          "lowercase"
        ]
      },
      "autocomplete_index": {
        "type": "custom",
        "tokenizer": "standard",
        "filter": [
          "lowercase",
          "autocomplete_filter"
        ]
      }
    }
  }
}

检查它是否已成功创建,我看到:

get http://localhost:9200/correntistas/_settings

{
    "correntistas": {
        "settings": {
            "index": {
                "number_of_shards": "5",
                "provided_name": "correntistas",
                "creation_date": "1586615323459",
                "analysis": {
                    "filter": {
                        "autocomplete_filter": {
                            "type": "edge_ngram",
                            "min_gram": "1",
                            "max_gram": "20"
                        }
                    },
                    "analyzer": {
                        "autocomplete_index": {
                            "filter": [
                                "lowercase",
                                "autocomplete_filter"
                            ],
                            "type": "custom",
                            "tokenizer": "standard"
                        },
                        "autocomplete_search": {
                            "filter": [
                                "lowercase"
                            ],
                            "type": "custom",
                            "tokenizer": "standard"
                        }
                    }
                },
                "number_of_replicas": "1",
                "uuid": "xtN-NOX3RQWJjeRdyC8CVA",
                "version": {
                    "created": "6080499"
                }
            }
        }
    }
}

到现在为止还挺好。

现在我使用 curl -XDELETE localhost:9200/correntistas 删除索引,我将执行相同的想法,但从 Postman 立即创建索引和分析器:

http://localhost:9200/correntistas与上面发布的完全相同的分析器放入:

立即创建索引和分析器

然后,如果我检查设置,我看到的结果与上面从 Spring-Data 创建的结果完全相同。

我是否错过了 Spring-Data 通过免费和隐藏的方式提供的一些额外步骤?

总而言之,当我从 Spring-data 创建时,我看到使用几个字母进行搜索,但是当我从邮递员创建时,它只是在我搜索整个单词时检索数据。

*** 多亏了 Opster Elasticsearch Ninja 的友好和聪明的帮助,我可以在这里添加一个我从 Postman 发帖时学到的额外技巧(不知何故,在我的 Postman 中启用的某些标题因“......根映射定义具有不受支持的参数而崩溃。 .. mapper_parsing_exception ...”在尝试解决方案时回答如下。我想在这里添加对未来的读者很有用。

邮递员标题搞砸了

标签: spring-bootelasticsearchspring-dataspring-data-elasticsearch

解决方案


由于您没有提供您在邮递员中使用的搜索查询,还有映射,这将有助于我们调试,如果您没有在字段上使用正确的分析器,那么您正在搜索查询中使用。此外,添加示例文档以及您的实际和预期搜索结果总是有帮助的。

Nvm,我添加了您的映射并在下面显示,以及如何使用邮递员,您将获得正确的结果。

索引def与您的完全相同

{
    "settings": {
        "analysis": {
            "filter": {
                "autocomplete_filter": {
                    "type": "edge_ngram",
                    "min_gram": 1,
                    "max_gram": 20
                }
            },
            "analyzer": {
                "autocomplete_search": {
                    "type": "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase"
                    ]
                },
                "autocomplete_index": {
                    "type": "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase",
                        "autocomplete_filter"
                    ]
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "name": {
                "type": "text",
                "analyzer": "autocomplete_index",
                "search_analyzer": "autocomplete_search"
            }
        }
    }
}

索引示例文档

{
    "name" : "opster"
}

{
    "name" : "jim c"
}

{
    "name" : "jimc"
}

{
    "name" : "foo"
}

搜索部分词,如ji带来jim cjimc文档

{
    "query": {
        "match": {
            "name": {
                "query": "ji"
            }
        }
    }
}

结果

  "hits": [
            {
                "_index": "61158504",
                "_type": "_doc",
                "_id": "2",
                "_score": 0.69263697,
                "_source": {
                    "name": "jimc"
                }
            },
            {
                "_index": "61158504",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.6133945,
                "_source": {
                    "name": "jim c"
                }
            }
        ]

推荐阅读