Elasti c Поиск - Как запросить одно-многократное объединение таблиц с AND - PullRequest
0 голосов
/ 10 января 2020

Я новичок в elasti c поиск. Могу ли я узнать, может ли следующий запрос быть выполнен с помощью поиска Elasti c? Если да, то как должна выглядеть строка запроса?

Ввод: sql подобное предложение. Предложение: «(A и B) и (C и D)»

A, B, C, D - сравнение полей. Например, поле A -> «Имя персонала» имеет значение, равное «Джону».

Например, есть 2 таблицы. Таблица сотрудников и таблица задач.

Таблица сотрудников

Имени персонала: Джон

Имени персонала: Мэри

Таблица задач

TaskName: JohnTaskA, StaffName: John

TaskName: JohnTaskB, StaffName: John

TaskName: MaryTaskA, StaffName: Mary

Так в традиционном DB, Джон может связать JohnTaskA и JohnTaskB как отношение 1 ко многим.

Мое ожидаемое поведение для поведения запросов (A и B) и (C и D) выглядит следующим образом:

После запроса (A и B) предположим, что возвращается только одна запись. John -> JohnTaskA

и после (C и D) запроса, предположим, вернуть только одну запись. John -> JohnTaskB

Затем следующие запросы (A и B) и (C и D) не должны возвращать значения, поскольку "John -> JohnTaskA" фактически не совпадает с "John -> JohnTaskB".

В противном случае, если (C и D) запрос, вернуть только одну запись в виде John -> JohnTaskB

Тогда следующий запрос (A и B) и (C и D) мог вернуть запись Джона обратно.

Но я не могу добиться этого ожидаемого поведения с помощью elasti c поискового запроса. В моей первой попытке я использую nestedQuery для обработки запроса таблицы задач и смог успешно выполнить проверку нескольких столбцов во вложенной таблице.

Например, если A -> Task.TaskName = JohnTaskA, B -> Task.StaffName = Джон, тогда A и B могут вернуть запись.

Но если A -> Task.TaskName = JohnTaskA, B -> Task.StaffName = Mary, то A и B не смогут вернуть любую запись.

Но я обнаружил, что в этом случае

(A и B) и (C и D)

Я не смог бы использовать средние "и", чтобы связать два вложенных результат запроса вместе. Он не возвращает ожидаемое поведение.

В случае, если предложение SQL не может быть изменено, могу ли я узнать, как поиск elasti c может выполнить этот запрос? или мне нужно использовать другие способы, такие как отношения между родителями и детьми?

Заранее спасибо за вашу помощь!


Для (A И B) И (C AND D),

(A И B) вернуть дочернюю запись с id = c1.

(C AND D) возвращает дочернюю запись с id = c2.

Даже если они совместно используют одну и ту же родительскую запись (скажем, идентификатор родительской записи = p1), поскольку c1! = C2, (A AND B) AND (C AND D) не возвращает запись, если запрос по SQL , Но используя elasti c search, он все равно возвращает запись p1.

1 Ответ

0 голосов
/ 11 января 2020

Я хотел бы предварить это, сказав, чтоasticsearch не является RDMS, и вы не должны использовать его как таковой. Вasticsearch гораздо лучше (производительность запросов, производительность репликации, производительность записи и т. Д.) Денормализовать ваши данные.

С учетом вышесказанного, поскольку у вас есть c запросы запросов, вы должны предварительно определить свой индекс отображение так, чтобы вы могли поддерживать отношения между объектами. Для этого вы можете использовать вложенные типы свойств или (в крайнем случае) join типы свойств в сопоставлениях.

Пример сопоставления, которое вы можете рассмотреть находится внутри индекса, который вы могли бы вызвать staff_tasks:

PUT staff_tasks
{
  "mappings": {
    "properties": {
      "task": {
        "type": "nested",
        "properties": {
          "name": {
            "type": "text",
          },
          "staff": {
            "type": "object",
            "properties": {
              "name": {
                "type": "text"
              }
            }
          }
        }
      }
    }
  }
}

Затем вы сможете запросить это с помощью API REST. Например, используя запрос на совпадение:

GET staff_tasks/_search
{
  "query": {
    "match": {
      "staff.name": "john"
    }
  }
}

Этот запрос вернет все staff_tasks кому как с именем "john" (без учета регистра) с информацией о "связанной" задаче в том же ответе.

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

POST _sql
{
  "query": "SELECT * FROM staff_tasks WHERE task.staff.name = 'john'"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...