ElasticSearch.NET / NEST - 所有 result.Hit 字段均为空(但结果在那里)
ElasticSearch.NET / NEST - All result.Hit fields are null (but results are there)
我的问题是,当我调用 .Search(...) 结果时,它 returns 为所有字段设置了所有空值(即使字段具有有效数据)。
我的班级是:
public class Member {
public string ID { get; set; }
public string ClientID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string PasswordHash { get; set; }
public string[] UserRoleIDs { get; set; }
}
我这样构建弹性客户端:
var node = new Uri("<correct url here>");
var config = new ConnectionSettings(node);
config.BasicAuthentication("elastic", "<correct password here>");
config.DisableDirectStreaming(true);
DB = new ElasticClient(config);
我这样查询 Elastic:
var res = DB.Search<Member>(s => s
.Index("members")
.Skip(0)
.Take(10)
.Query(q => q
.Term(t => t.EmailAddress, emailAddress)
)
);
我得到的结果是 200 OK,有 Hits 和 Documents,两者都有我正在搜索的记录的正确 ID(查询按预期成功)。
我也可以将 res.ApiCall.ResponseBodyInBytes 评估为一个字符串,我可以看到弹性返回的 JSON 是正确的(字段有数据)。
BUT.. res.Document.FirstOrDefault() returns a "Member" class 其中所有字段均为 NULL(强调一下,JSON 的值为为空的字段)。
我尝试将其更改为使用 Dictionary 而不是我的 Member 对象,这似乎工作正常(例如 myDictionary["FirstName"] == "Dan")。
此外,我尝试使用搜索结果给我的 ID 并调用:
var user = DB.Get<Member>(id, i => i.Index("members"));
这有相同的最终结果,user.Hit的所有字段都是空的:(
问题似乎出在属性的大小写上。当我刚开始使用 ES 和 .Net 时,我也遇到了同样的问题。如果您已通过 C# Nest 代码对其进行索引,则 Class 成员的属性将已从 PascalCase 转换为驼峰式,并将被索引为驼峰式。因为在 ES 中默认 fields/properties 应该是驼峰式的。
如果您没有通过 C# Nest 客户端和 PostMan 或其他 API 客户端编制索引,并且如果出现在 JSON 中的属性有 PascalCase,那么它们将不会映射到您的对象同样的原因。
如果您使用 PostMan 或类似的东西进行索引,请尝试将 ES 文档中的属性从 PascalCase 更改为 camelCase。
否则尝试通过 C# Nest Client 建立索引。下面是一个通过 C# Nest Client 建立索引的例子(如果你使用的是 Nest v7.x),如果有多个文档要建立索引:
Member[] members = new Member[10];
//some code to add Member class objects to members array.
var bulkIndexResponse = DB.BulkAsync(b => b.("members").IndexMany(members));
使用 [Nest.PropertyName("json_key")] 尤其是对于带有下划线的键
我的问题是,当我调用 .Search(...) 结果时,它 returns 为所有字段设置了所有空值(即使字段具有有效数据)。
我的班级是:
public class Member {
public string ID { get; set; }
public string ClientID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string PasswordHash { get; set; }
public string[] UserRoleIDs { get; set; }
}
我这样构建弹性客户端:
var node = new Uri("<correct url here>");
var config = new ConnectionSettings(node);
config.BasicAuthentication("elastic", "<correct password here>");
config.DisableDirectStreaming(true);
DB = new ElasticClient(config);
我这样查询 Elastic:
var res = DB.Search<Member>(s => s
.Index("members")
.Skip(0)
.Take(10)
.Query(q => q
.Term(t => t.EmailAddress, emailAddress)
)
);
我得到的结果是 200 OK,有 Hits 和 Documents,两者都有我正在搜索的记录的正确 ID(查询按预期成功)。
我也可以将 res.ApiCall.ResponseBodyInBytes 评估为一个字符串,我可以看到弹性返回的 JSON 是正确的(字段有数据)。
BUT.. res.Document.FirstOrDefault() returns a "Member" class 其中所有字段均为 NULL(强调一下,JSON 的值为为空的字段)。
我尝试将其更改为使用 Dictionary 而不是我的 Member 对象,这似乎工作正常(例如 myDictionary["FirstName"] == "Dan")。
此外,我尝试使用搜索结果给我的 ID 并调用:
var user = DB.Get<Member>(id, i => i.Index("members"));
这有相同的最终结果,user.Hit的所有字段都是空的:(
问题似乎出在属性的大小写上。当我刚开始使用 ES 和 .Net 时,我也遇到了同样的问题。如果您已通过 C# Nest 代码对其进行索引,则 Class 成员的属性将已从 PascalCase 转换为驼峰式,并将被索引为驼峰式。因为在 ES 中默认 fields/properties 应该是驼峰式的。
如果您没有通过 C# Nest 客户端和 PostMan 或其他 API 客户端编制索引,并且如果出现在 JSON 中的属性有 PascalCase,那么它们将不会映射到您的对象同样的原因。
如果您使用 PostMan 或类似的东西进行索引,请尝试将 ES 文档中的属性从 PascalCase 更改为 camelCase。
否则尝试通过 C# Nest Client 建立索引。下面是一个通过 C# Nest Client 建立索引的例子(如果你使用的是 Nest v7.x),如果有多个文档要建立索引:
Member[] members = new Member[10];
//some code to add Member class objects to members array.
var bulkIndexResponse = DB.BulkAsync(b => b.("members").IndexMany(members));
使用 [Nest.PropertyName("json_key")] 尤其是对于带有下划线的键