Elasticsearch 对映射 put 方法的错误请求
Elasticsearch bad request on mapping put method
我正在尝试在 Elastic Search 中创建一个索引,并添加分析器和 maaping 来处理 @ 等特殊字符,以便在电子邮件字段中进行搜索。这是我的代码
Analyzer.txt
{
"analysis": {
"analyzer": {
"email_search": {
"type": "custom",
"tokenizer": "uax_url_email",
"filter": [ "lowercase", "stop" ]
}
}
}
Mapping.txt
{"users":
{
"properties": {
"email": {
"type": "string",
"analyzer": "email_search"
}
}
}
CreatedIndex
string _docuementType ="users";
string _indexName="usermanager";
public bool Index(T entity)
{
SetupAnalyzers();
SetupMappings();
var indexResponse = _elasticClient.Index(entity, i => i.Index(_indexName)
.Type(_docuementType)
.Id(entity.Id));
return indexResponse.IsValid;
}
设置分析器
protected void SetupAnalyzers()
{
if (!_elasticClient.IndexExists(_indexName).Exists)
{
_elasticClient.CreateIndex(_indexName);
}
using (var client = new System.Net.WebClient())
{
string analyzers = File.ReadAllText("analyzers.txt");
client.UploadData("http://localhost:9200/usermanager/_settings", "PUT", Encoding.ASCII.GetBytes(analyzers));
}
}
SetupMappings
protected void SetupMappings()
{
using (var client = new System.Net.WebClient())
{
var mappings = File.ReadAllText("mappings.txt");
client.UploadData("http://localhost:9200/usermanager/users/_mapping", "PUT", Encoding.ASCII.GetBytes(mappings));
}
}
但是在 SetupMappings 方法上出现错误
The remote server returned an error: (400) Bad Request.
Elastic 版本为 1.7.5
Nest 版本为 5.5
问题是
var indexResponse = _elasticClient.Index(entity, i => i.Index(_indexName)
.Type(_docuementType)
.Id(entity.Id));
您正在索引文档之前设置映射和分析器;在这种情况下,Elasticsearch 将自动创建索引,从它看到的第一个文档推断出一个映射,并且字符串属性将使用标准分析器映射为 analyzed string fields。
要解决此问题,您应该在 为任何文档编制索引之前创建索引、分析器和映射。你也可以disable auto index creation if you need to, in elasticsearch.yml config。这是否是个好主意取决于您的用例;具有已知索引和显式映射的搜索用例是您可以考虑禁用它的情况。
因此,程序流程类似于
void Main()
{
var indexName = "usermanager";
var typeName = "users";
var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
.MapDefaultTypeNames(d => d
// map the default index to use for the User type
.Add(typeof(User), typeName)
)
.MapDefaultTypeIndices(d => d
// map the default type to use for the User type
.Add(typeof(User), indexName)
);
var client = new ElasticClient(settings);
if (!client.IndexExists(indexName).Exists)
{
client.CreateIndex(indexName, c => c
.Analysis(a => a
.Analyzers(aa => aa
.Add("email_search", new CustomAnalyzer
{
Tokenizer = "uax_url_email",
Filter = new [] { "lowercase", "stop" }
})
)
)
.AddMapping<User>(m => m
.Properties(p => p
.String(s => s
.Name(n => n.Email)
.Analyzer("email_search")
)
)
)
);
}
client.Index(new User { Email = "me@example.com" });
}
public class User
{
public string Email { get; set; }
}
这将发送以下请求(假设索引不存在)
HEAD http://localhost:9200/usermanager
POST http://localhost:9200/usermanager
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"email_search": {
"tokenizer": "uax_url_email",
"filter": [
"lowercase",
"stop"
],
"type": "custom"
}
}
}
}
},
"mappings": {
"users": {
"properties": {
"email": {
"analyzer": "email_search",
"type": "string"
}
}
}
}
}
POST http://localhost:9200/usermanager/users
{
"email": "me@example.com"
}
注意:您需要删除索引并重新创建,以更改映射。使用别名与索引交互是个好主意,这样您就可以在开发过程中迭代映射。
我正在尝试在 Elastic Search 中创建一个索引,并添加分析器和 maaping 来处理 @ 等特殊字符,以便在电子邮件字段中进行搜索。这是我的代码
Analyzer.txt
{
"analysis": {
"analyzer": {
"email_search": {
"type": "custom",
"tokenizer": "uax_url_email",
"filter": [ "lowercase", "stop" ]
}
}
}
Mapping.txt
{"users":
{
"properties": {
"email": {
"type": "string",
"analyzer": "email_search"
}
}
}
CreatedIndex
string _docuementType ="users";
string _indexName="usermanager";
public bool Index(T entity)
{
SetupAnalyzers();
SetupMappings();
var indexResponse = _elasticClient.Index(entity, i => i.Index(_indexName)
.Type(_docuementType)
.Id(entity.Id));
return indexResponse.IsValid;
}
设置分析器
protected void SetupAnalyzers()
{
if (!_elasticClient.IndexExists(_indexName).Exists)
{
_elasticClient.CreateIndex(_indexName);
}
using (var client = new System.Net.WebClient())
{
string analyzers = File.ReadAllText("analyzers.txt");
client.UploadData("http://localhost:9200/usermanager/_settings", "PUT", Encoding.ASCII.GetBytes(analyzers));
}
}
SetupMappings
protected void SetupMappings()
{
using (var client = new System.Net.WebClient())
{
var mappings = File.ReadAllText("mappings.txt");
client.UploadData("http://localhost:9200/usermanager/users/_mapping", "PUT", Encoding.ASCII.GetBytes(mappings));
}
}
但是在 SetupMappings 方法上出现错误
The remote server returned an error: (400) Bad Request.
Elastic 版本为 1.7.5
Nest 版本为 5.5
问题是
var indexResponse = _elasticClient.Index(entity, i => i.Index(_indexName)
.Type(_docuementType)
.Id(entity.Id));
您正在索引文档之前设置映射和分析器;在这种情况下,Elasticsearch 将自动创建索引,从它看到的第一个文档推断出一个映射,并且字符串属性将使用标准分析器映射为 analyzed string fields。
要解决此问题,您应该在 为任何文档编制索引之前创建索引、分析器和映射。你也可以disable auto index creation if you need to, in elasticsearch.yml config。这是否是个好主意取决于您的用例;具有已知索引和显式映射的搜索用例是您可以考虑禁用它的情况。
因此,程序流程类似于
void Main()
{
var indexName = "usermanager";
var typeName = "users";
var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
.MapDefaultTypeNames(d => d
// map the default index to use for the User type
.Add(typeof(User), typeName)
)
.MapDefaultTypeIndices(d => d
// map the default type to use for the User type
.Add(typeof(User), indexName)
);
var client = new ElasticClient(settings);
if (!client.IndexExists(indexName).Exists)
{
client.CreateIndex(indexName, c => c
.Analysis(a => a
.Analyzers(aa => aa
.Add("email_search", new CustomAnalyzer
{
Tokenizer = "uax_url_email",
Filter = new [] { "lowercase", "stop" }
})
)
)
.AddMapping<User>(m => m
.Properties(p => p
.String(s => s
.Name(n => n.Email)
.Analyzer("email_search")
)
)
)
);
}
client.Index(new User { Email = "me@example.com" });
}
public class User
{
public string Email { get; set; }
}
这将发送以下请求(假设索引不存在)
HEAD http://localhost:9200/usermanager
POST http://localhost:9200/usermanager
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"email_search": {
"tokenizer": "uax_url_email",
"filter": [
"lowercase",
"stop"
],
"type": "custom"
}
}
}
}
},
"mappings": {
"users": {
"properties": {
"email": {
"analyzer": "email_search",
"type": "string"
}
}
}
}
}
POST http://localhost:9200/usermanager/users
{
"email": "me@example.com"
}
注意:您需要删除索引并重新创建,以更改映射。使用别名与索引交互是个好主意,这样您就可以在开发过程中迭代映射。