Запрос Elasticsearch в. net NEST не инициализирует объект - PullRequest
0 голосов
/ 29 апреля 2020

Я начал с NEST в. NET для реализации запросов 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? Или класс должен быть создан из ответа JSON при отображении данных в ES?

Вот мой класс

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"
            }
          }
        }
      }
    ]
  }
}

1 Ответ

0 голосов
/ 30 апреля 2020

По умолчанию NEST отображает имена свойств POCO, которые Pascal, в верблюжьих 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);
...