Накратко опишете как да съхранявате сложни релационни данни в ElasticSearch

В традиционната база данни описанието на връзката с данни е нищо повече от три отношения, едно към едно, един към много и много към много. Ако има данни, свързани с връзката, обикновено добавяме основния чужд ключ при изграждането на таблицата. Установете връзки за данни, след това възстановете или завършете данните чрез присъединяване в заявката или статистиката и накрая вземете данните за резултатите, от които се нуждаем, след това преобразувайте в ElasticSearch, как или как да се справите с тези релационни данни.

Всички знаем, че ElasticSearch е база данни от тип NoSQL, която отслабва обработката на взаимоотношенията, тъй като рамките за търсене в пълен текст като lucene, es и solr имат по-високи изисквания за производителност. След като се извърши операция за присъединяване, производителността ще бъде много лоша, така че когато използваме рамката за търсене, трябва да избягваме използването на търсачката като релационна база данни.

Разбира се, действителните данни определено са свързани, така че как се справяте и управлявате тези релационни данни в es?

Всеки знае, че es, родени да поддържат json данни, са перфектни, стига стандартната структура на json от данни, независимо колко сложни, независимо колко слоя са вложени, могат да се съхраняват в es и след това могат да бъдат заявени и анализирани, извлечени , В този механизъм има три основни начина за справяне и управление на взаимоотношенията:

Първо, използвайте видовете полета objcet и масив [object], за да съхранявате автоматично json данните на многослойната структура.

Това е механизмът по подразбиране на es, тоест ние не сме задали никакво картографиране, директно вмъкваме сложни данни json в es сървъра, също можем успешно да вмъкнем и може да поддържам извличане (това може да стане, защото подразбирането на es е динамично картографиране , докато стандартната структура на json се вмъкне автоматично ще се преобразува, разбира се, можем да контролираме и типа картографиране, т.е. вътре в динамичното картографиране и статичното картографиране, статичното картографиране също е разделено на строг тип, слаб тип, общ тип, вече не разширете тук Заинтересованите могат да научат от официалния уебсайт) като една от следните данни:

{
  "име": "Zach",
  "кола"  : [
    {
      "марката": "Сатурн",
      "модел": "SL"
    }
    {
      "марката": "Subaru",
      "модел": "Импреза"
    }
  ]
}

Получената структура за съхранение е подобна на следното:

{
  "име": "Zach",
  "car.make": ["Сатурн", "Субару"]
  "car.model": ["SL", "Imprezza"]
}

Тъй като базовият лучен на es е естествена поддръжка за многоценно съхранение, той изглежда като структура от масив отгоре. Всъщност es се съхранява в това поле като поле с много стойност.

След това, когато търсите, символът може да извлече съответното съдържание. Такава част от данните всъщност съдържа данни и взаимоотношения. Изглежда като връзка между мнозина. Човек притежава няколко автомобила. Но всъщност не е строга връзка, тъй като долният луценов слой се съхранява плоско, така че данните от множество коли всъщност са смесени заедно, не можете да получите кола само от този човек. Данните, тъй като всички данни са цяло, без значение каква операция ще бъдат върнати.

Второ, използвайте вложен тип [object], за да съхранявате данни с многостепенни отношения

В сценарий 1 посочихме, че обектите от масива, съхранявани в масива, не са строго свързани, тъй като данните на втория слой не са разделени. Ако искате да се разделите, трябва да използвате вложен тип, за да дефинирате изрично структурата на данните. Само по този начин множествените данни за автомобила на втория слой са независими един от друг, тоест данните за определен автомобил могат да бъдат получени или запитвани отделно.

Същите данни json:

{
  "име": "Zach",
  "кола"  : [
    {
      "марката": "Сатурн",
      "модел": "SL"
    }
    {
      "марката": "Subaru",
      "модел": "Импреза"
    }
  ]
}

В сценарий 1, крайният es ще съхранява част от данните във втория тип и ако типът автомобил е деклариран вложен, тогава броят на es, съхранени на финала, ще се покаже 3, тук обяснете как идва 3 = 1 корен документ + 2 документа за кола, вложен тип декларация, всеки инстанция е нов документ, така че може да бъде независимо заявен при заявки, а производителността не е лоша, тъй като дъното на es ще има същите данни. недостатъкът е, че цената на актуализацията е сравнително голяма, всяка актуализация на поддокумента трябва да възстанови индекса на цялата структура, така че вложен е подходящ за сценарии на вложени връзки на много нива, които не се актуализират често.

Вложени данни от типа, за да влезете в сила, трябва да използвате определените му методи за заявки и агрегиране, обикновената заявка на es може да запитва само атрибути на ниво 1 или на ниво корен, вложени атрибути не могат да бъдат проверявани, ако искате да проверите, трябва да използвате вграден набор от запитвания или обобщения.

Вложените приложения имат два режима:

  • Въведена заявка
    Всяка заявка е валидна в рамките на един документ, включително сортиране
  • Вложено агрегиране или филтриране
    Всички документи от едно и също ниво са валидни в световен мащаб, включително сортиране за филтриране

Трето, връзката родител / деца

Моделът родител / деца е много подобен на вложен, но фокусът на приложението е различен.

Когато използва родител / деца за управление на асоциации, es поддържа релационна таблица в паметта на всеки фрагмент. Когато бъдат извлечени, свързаните данни се получават от филтрите has_parent и has_child. В този режим се използват родителският документ и поддокументите. Освен това е независима, производителността на заявката ще бъде малко по-ниска от вложен режим, тъй като родителският документ и поддокументът ще бъдат разпределени в един и същ фрагмент по маршрута, когато са вмъкнати, но не е гарантирано, че са в един и същ индекс на луксозната сегментация сегмент, така че ефективността на извличане е малко по-ниска. Освен това, всеки път, когато изтегляте es, трябва да получавате информацията за свързване на данни от таблицата за връзка с паметта. Това също отнема известно време. Предимството на вложеното е, че родителският документ или поддокументът се актуализира. Това не засяга други документи, така че е най-подходящо да се използва режима родител / деца за актуализиране на чести връзки на много нива.

Тип на картографиране на родителския документ:

{
  „картографиране“: {
    "лице": {
      "име": {
        "type": "string"
      }
    }
  }
}

Тип картографиране на поддокумента:

{
  „домове“: {
    "_parent": {
      "type": "лице"
    }
    "държава": {
      "type": "string"
    }
  }
}

Когато въвеждате данни, първо трябва да поставите родителския документ:

curl -XPUT localhost: 9200 / тест / човек / zach / -d '
{
  "име": "Zach"
}

След това, когато поставите поддокумент, трябва да добавите поле за маршрутизиране:

$ curl -XPOST localhost: 9200 / домове? parent = zach -d '
{
  "държава": "Охайо"
}
$ curl -XPOST localhost: 9200 / тест / домове? parent = zach -d '
{
  "държава": "Южна Каролина"
}

Да обобщим:

метод първи:

  1. Проста, бърза и висока производителност
  2. Добър в поддържането на отношенията един към един
  3. Не се изисква специално запитване

Метод втори:

  1. Тъй като базовият слой се съхранява в една и съща луценова сегмента, методът за сравнение на четене и заявка за сравнение е по-бърз.
  2. Актуализирането на един поддокумент ще възстанови цялата структура на данните, така че не е подходящо за актуализиране на чести вложени сцени.
  3. може да поддържа връзки за съхранение между много и много

Метод три:

  1. Множество релационни данни, съхранението е напълно независимо, но съществува в един и същ фрагмент, така че ефективността на четене и запитване е малко по-ниска от втория метод.
  2. Нуждаете се от допълнителна памет, поддържайте списък с отношения на управление
  3. Актуализирането на документа не засяга други поддокументи, така че е подходящо за актуализиране на често използвани сцени.
  4. Операциите за сортиране и оценяване са тромави и изискват допълнителна поддръжка на скрипт

Всеки метод има свой подходящ сценарий за приложение, така че на практика трябва да изберем подходящия метод за съхранение според реалния бизнес сценарий