Хранить смешанный тип данных в ElasticSearch

Я использую logstash для управления журналами приложений. Я хочу сохранить некоторые данные контекста вместе с записями журнала. Эти контекстные данные не нужно индексировать. Но он может иметь разную структуру/тип данных в зависимости от контекста приложения. Например, контекст может быть в любом из следующих форматов.

Нить

{
    error: "This is a sample error message"
}

Множество

{
    error: [
        "This is an error message", 
        "This is another message", 
        "This is the final message"
    ]
}

Или это может быть объект

{
    error: {
        user_name: "Username cannot be empty",
        user_email: "Email address is already in use",
        user_password: "Passwords do not match"
    }
}

Возможно ли иметь такое поле в ElasticSearch? Поле не нужно индексировать, его просто нужно сохранить.


person Joyce Babu    schedule 08.01.2015    source источник
comment
Вы можете взглянуть на это: orchestrate.io/blog/2014. /09/30/улучшенное эластичное поисковое индексирование   -  person Mandeep Singh    schedule 16.09.2015
comment
Наткнулся на это при использовании стека ELK в качестве свалки для логирования. Как только поле входит в качестве типа, побеждает первый тип (сопоставленный со схемой за кулисами с помощью elasticsearch), и добавление ignore_malformed, похоже, также не решило наши проблемы. Просто оставлю это здесь, вдруг кому пригодится.   -  person Matt Sanders    schedule 24.09.2015


Ответы (1)


Я не думаю, что возможно сделать именно то, что вы просите. Вы можете получить первые два примера бесплатно, так как любое поле может быть списком:

curl -XDELETE "http://localhost:9200/test_index"

curl -XPUT "http://localhost:9200/test_index" -d'
{
    "mappings": {
        "doc": {
            "properties": {
                "error": {
                    "type": "string",
                    "index": "not_analyzed"
                }
            }
        }
    }
}'

curl -XPUT "http://localhost:9200/test_index/doc/1" -d'
{
    "error": "This is a sample error message"
}'

curl -XPUT "http://localhost:9200/test_index/doc/2" -d'
{
    "error": [
        "This is an error message", 
        "This is another message", 
        "This is the final message"
    ]
}'

curl -XPOST "http://localhost:9200/test_index/_search"
...
{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 2,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1",
            "_score": 1,
            "_source": {
               "error": "This is a sample error message"
            }
         },
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "2",
            "_score": 1,
            "_source": {
               "error": [
                  "This is an error message",
                  "This is another message",
                  "This is the final message"
               ]
            }
         }
      ]
   }
}

В качестве альтернативы вы можете настроить сопоставление в соответствии с вашим третьим примером, а затем просто использовать поля, необходимые для каждого документа (предположительно, усложняя код вашего приложения):

curl -XDELETE "http://localhost:9200/test_index"

curl -XPUT "http://localhost:9200/test_index"

curl -XPUT "http://localhost:9200/test_index/doc/3" -d'
{
    "error": {
        "user_name": "Username cannot be empty",
        "user_email": "Email address is already in use",
        "user_password": "Passwords do not match"
    }
}'

curl -XGET "http://localhost:9200/test_index/_mapping"
...
{
   "test_index": {
      "mappings": {
         "doc": {
            "properties": {
               "error": {
                  "properties": {
                     "user_email": {
                        "type": "string"
                     },
                     "user_name": {
                        "type": "string"
                     },
                     "user_password": {
                        "type": "string"
                     }
                  }
               }
            }
         }
      }
   }
}

Так что в основном прямой ответ на ваш вопрос - «Нет», если я что-то не упустил (что вполне возможно).

Вот код, который я использовал:

http://sense.qbox.io/gist/18476aa6c2ad2fa554b472d09934559c884bec33

person Sloan Ahrens    schedule 08.01.2015
comment
Спасибо. любое поле может быть списком новой информации. Я подожду несколько дней, прежде чем отметить это как ответ. - person Joyce Babu; 09.01.2015