Как ссылаться на несколько полей при добавлении документа вasticsearch - PullRequest
0 голосов
/ 13 июня 2019

Я создал индекс на своем сервере Elasticsearch и использую .NET-клиент NEST для подключения к нему. Некоторые свойства индекса имеют несколько полей, и я хочу заполнить только правильное поле.

Я создал класс 'document' для этого отображения. но я не знаю, как получить доступ к полям собственности.

это отображение, которое я имею (суммировано):

"mappings": {
      "document": {
        "properties": {

          "baseUniqueID": {
            "type": "keyword"
          },
          "description": {
            "type": "text",
            "fields": {
              "en": {
                "type": "text",
                "analyzer": "english"
              },
              "fa": {
                "type": "text",
                "analyzer": "nofapersian"
              },
              "fr": {
                "type": "text",
                "analyzer": "french"
              }
            }
          },
          "documentDate": {
            "type": "date"
          },
          "documentType_Id": {
            "type": "keyword"
          },
          "id": {
            "type": "long"
          }

        }
      }
    }

и класс документа:

public class Document : BaseInt32KeyEntity
    {
        public string BaseUniqueID{ get; set; }

        public int? Weight { get; set; }

        public DateTime DocumentDate { get; set; }

        public string Description { get; set; }

        public int DocumentType_Id { get; set; }
    }
}

Как я могу сделать объект Document для заполнения только нужного мне поля (здесь, в этом примере description.en), а затем использовать IndexDocument, чтобы добавить его в Elasticsearch? как то так:

Document doc = new Document();
doc.Description.en = "This is some description";
ElasticClient.IndexDocument(doc);

1 Ответ

1 голос
/ 14 июня 2019

Вы можете обновить отдельное поле с помощью API обновлений

var client = new ElasticClient();

var documentId = 1;

var partial = new 
{
    Description = "This is some description"
};

var updateResponse = client.Update<Document, object>(documentId, u => u
    .Index("your_index")
    .Doc(partial)
);

.Index() требуется только в том случае, если вы не настроили соглашение об индексе для типа Document.Документ для обновления моделируется частичным документом, поскольку использование Document приведет к отправке значений по умолчанию для типов значений, таких как свойства DocumentDate и DocumentType_Id.

doc.Description.en =«Это какое-то описание»;

Это невозможно сделать, так как это не так, как работает multi-field .В случае нескольких полей входные данные одного поля документа можно анализировать различными способами для удовлетворения различных потребностей поиска.В вашем примере значение свойства Description будет проанализировано 4 различными способами:

  1. стандартным анализатором с базовым text отображением
  2. анализатором английского языка с .en многопольное отображение
  3. с помощью nofapersian анализатора с .fa многопольным отображением
  4. с помощью французского анализатора с .fr многопольным отображением

Результаты анализа будут проиндексированы в инвертированном индексе, чтобы вы могли искать и запрашивать их, но исходный документ JSON, отправленный в Elasticsearch, будет содержать только одно поле "description", которое вы получите, когда вы вернетесьполучить _source для документа (если _source сохранено, что по умолчанию это так).

Если вы хотите смоделировать их как отдельные поля в документе, вы можете ввести Description тип, который имеет необходимые свойства

public class Description
{
    public string Standard { get;set; }
    public string English { get;set; }
    public string NoFaPersian{ get;set; }
    public string French{ get;set; }
}

, а затем индексировать его как object отображение типа, настраивая анализатор для каждого

public class Document
{
    public string BaseUniqueID { get; set; }
    public int? Weight { get; set; }
    public DateTime DocumentDate { get; set; }
    public Description Description { get; set; }
    public int DocumentType_Id { get; set; }
}

var indexResponse = client.CreateIndex("your_index", c => c
    .Mappings(m => m
        .Map<Document>(mm => mm
            .AutoMap()
            .Properties(p => p
                .Object<Description>(o => o
                    .Name(n => n.Description)
                    .AutoMap()
                    .Properties(pp => pp
                        .Text(t => t.Name(n => n.Standard).Analyzer("standard"))
                        .Text(t => t.Name(n => n.English).Analyzer("english"))
                        .Text(t => t.Name(n => n.NoFaPersian).Analyzer("nofapersian"))
                        .Text(t => t.Name(n => n.French).Analyzer("french"))
                    )
                )
            )
        )
    )       
);

, который производит foзапрос на создание индекса

PUT http://localhost:9200/your_index?pretty=true 
{
  "mappings": {
    "document": {
      "properties": {
        "baseUniqueID": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "weight": {
          "type": "integer"
        },
        "documentDate": {
          "type": "date"
        },
        "description": {
          "type": "object",
          "properties": {
            "standard": {
              "type": "text",
              "analyzer": "standard"
            },
            "english": {
              "type": "text",
              "analyzer": "english"
            },
            "noFaPersian": {
              "type": "text",
              "analyzer": "nofapersian"
            },
            "french": {
              "type": "text",
              "analyzer": "french"
            }
          }
        },
        "documentType_Id": {
          "type": "integer"
        }
      }
    }
  }
}
...