首页 > 解决方案 > .net NEST 中的 Elasticsearch 查询未初始化对象

问题描述

我从 .NET 中的 NEST 开始用于实现 ElasticSearch 查询,我一开始就面临问题,为什么不使用以下语句创建对象。

var searchResponse = client.Search<TestDto>(sd => sd
            .Index("qa-report")
            .Size(1)
            .Query(q => q
                .Match(m => m.Field("TestId").Query("CX001")
                )));

执行时,对象searchResponse.Documents包含TestDto空。我不确定这TestDto是否正确。如何从 ElasticSeach 映射轻松创建它?还是在 ES 中显示数据时必须从 JSON 响应创建类?

这是我的课

public class TestDto
{
    public class Platform
    {
        public string BrowserName { get; set; }
        public string OS { get; set; }
        public string OsVersion { get; set; }
    }

    public class MachineInfo
    {
        public string IP { get; set; }
        public string Name { get; set; }
        public string User { get; set; }
    }

    public class MetaData
    {
        public string Environment { get; set; }
        public Platform Platform { get; set; }
        public double DurationMs { get; set; }
        public string TestName { get; set; }
        public string SuiteName { get; set; }
        public IList<string> Categories { get; set; }
        public string ExceptionsStr { get; set; }
        public object LastException { get; set; }
        public object Priority { get; set; }
        public object TestSuiteId { get; set; }
        public string TestStatusStr { get; set; }
        public string Logs { get; set; }
        public string LastMessage { get; set; }
        public string JobName { get; set; }
        public string BuildNumber { get; set; }
        public string TestRunId { get; set; }
        public MachineInfo MachineInfo { get; set; }
    }

    public class Example
    {
        public string TestId { get; set; }
        public string PlatformStr { get; set; }
        public string Duration { get; set; }
        public string ResultMessage { get; set; }
        public int TestStatus { get; set; }
        public string ResultId { get; set; }
        public DateTime Created { get; set; }
        public IList<object> Issues { get; set; }
        public MetaData MetaData { get; set; }
    }
}

这是我在 ES 中得到的回复:

{
  "took": 13,
  "timed_out": false,
  "_shards": {
    "total": 90,
    "successful": 90,
    "failed": 0
  },
  "hits": {
    "total": 1643,
    "max_score": 10.439584,
    "hits": [
      {
        "_index": "qa-report",
        "_type": "qa-report",
        "_id": "445.0",
        "_score": 10.439584,
        "_source": {
          "TestId": "CX001",
          "PlatformStr": "windows_10_chrome_+",
          "Duration": "00:00:05.2530435",
          "ResultMessage": """
None
""",
          "TestStatus": 4,
          "ResultId": "e338ca8b-dd95-4f57-9bed-20d0e65efc4c",
          "Created": "2019-11-29T06:01:48.617172Z",
          "Issues": [],
          "MetaData": {
            "Environment": "local",
            "Platform": {
              "BrowserName": "chrome",
              "OS": "windows",
              "OsVersion": "10"
            },
            "DurationMs": 5253.043500000001,
            "TestName": "TestName",
            "SuiteName": "SuiteName",
            "Categories": [
              "Cat1",
              "Cat2"
            ],
            "ExceptionsStr": """
None
""",
            "LastException": {
              "Type": "System.InvalidOperationException",
              "Message": "Sequence contains no matching element",
              "StackTrace": """
None
"""
            },
            "Priority": null,
            "TestSuiteId": null,
            "TestStatusStr": "Failed",
            "Logs": """
None
""",
            "LastMessage": """
None
""",
            "JobName": "Job1",
            "BuildNumber": "10",
            "TestRunId": "LTestRunId1",
            "MachineInfo": {
              "IP": "10",
              "Name": "PI",
              "User": "PO"
            }
          }
        }
      }
    ]
  }
}

标签: .netelasticsearchnest

解决方案


默认情况下,NEST 将 Pascal 大小写的 POCO 属性名称映射到骆驼大小写的 JSON 对象属性名称。例如

public class Platform
{
    public string BrowserName { get; set; }
    public string OS { get; set; }
    public string OsVersion { get; set; }
}

将映射到以下 JSON

{
    "browserName": "",
    "oS": "",
    "osVersion": ""
}

NEST 7.x 对这种大小写非常严格。由于 Elasticsearch 的结果包含 Pascal 大小写的 JSON 属性名称,我们需要告诉 NEST 期待 Pascal 大小写的属性。这可以在全球范围内完成DefaultFieldNameInferrer

var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
    .DefaultFieldNameInferrer(p => p); // <-- add this

var client = new ElasticClient(settings);

推荐阅读