Запрос вложенных объектов Grails 3 ElasticSearch с ограничением ownTo, дающим неправильные совпадения

Я хочу выполнить поиск в своем доменном классе с помощью ElasticSearch, но это вложенный запрос, и совпадение, которое я хочу, имеет три уровня глубины.

Только класс домена, из которого я ищу, установлен как root, все остальные установлены как компоненты, а не root для конфигурации с возможностью поиска.

Когда я выполняю поиск, он дает мне совпадения, но подсчет неправильный, и внутри есть совершенно неправильные совпадения.

Я должен получить 4000 совпадений, но я получаю 20000 совпадений, и я понятия не имею, почему это не работает должным образом.

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

Я собираюсь привести два примера. Первый показывает отношения моих классов домена в настоящее время (тот, который не работает), а другой - с изменением, которое заставило поиск работать правильно.

Неправильно работающий пример

class A {
    String id
    String name

    B b

    static searchable = {
        b component: true
    }
}

class B {
    String id
    String name

    C c

    static searchable = {
        root false
        c component: true
    }
}

class C {
    String id
    String name

    static belongsTo = [d: D]

    static searchable = {
        root false
        d component: true
    }
}

class D {
    String id
    String name

    static searchable = {
        root false
    }
}

Правильно работающий пример

class A {
    String id
    String name

    B b

    static searchable = {
        b component: true
    }
}

class B {
    String id
    String name

    C c

    static searchable = {
        root false
        c component: true
    }
}

class C {
    String id
    String name

    D d

    static searchable = {
        root false
        d component: true
    }
}

class D {
    String id
    String name

    static searchable = {
        root false
    }
}

Как видите, единственная разница в отношениях заключается в том, что в первом примере класс D принадлежит классу C, а во втором примере класс D является просто полем в классе C. В базе данных D ссылается в C точно так же в обоих случаях. .

Закрытие поиска, которое я создал, выглядит следующим образом:

bool {
    must {
        nested {
            path = "b"
            query {
                nested {
                    path = "b.c"
                    query {
                        path = "b.c.d"
                        query {
                            bool {
                                must {
                                    match("b.c.d.id": "142342342342")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Мне действительно нужно изменить свои отношения для классов предметной области, чтобы поиск работал, или я просто неправильно выполняю поиск?

Что может вызвать проблему в целом?

ИЗМЕНИТЬ

Отображение ElasticSearch для поля «d» внутри «c» в обоих случаях одинаково:

"c":{  
                    "type":"nested",
                    "properties":{  
                       "class":{  
                          "type":"string"
                       },
                       "dateCreated":{  
                          "type":"date",
                          "format":"strict_date_optional_time||epoch_millis",
                          "include_in_all":true
                       },
                       "d":{  
                          "type":"nested",
                          "properties":{  
                             "class":{  
                                "type":"string"
                             },
                             "id":{  
                                "type":"string"
                             },
                             "name":{  
                                "type":"string",
                                "term_vector":"with_positions_offsets",
                                "include_in_all":true
                             }
                          }
                       }

ИЗМЕНИТЬ 2

Таким образом, похоже, что проблема была не в сопоставлениях, а скорее в том, что при выполнении поиска как минимум с тремя уровнями вложенных объектов ElasticSearch не смог правильно найти совпадения со словом match. У меня все работает с match_phrase.

Так что важный урок, когда вы ищете, например, идентификаторы, и ваш запрос имеет многоуровневую вложенность, и вы хотите точное совпадение, тогда следует использовать match_phrase!


person siimval    schedule 28.04.2017    source источник
comment
Можете ли вы показать сопоставление, созданное для варианта A (с belongsTo) и варианта B (без)?   -  person Val    schedule 28.04.2017
comment
Я посмотрел на сопоставления и обновил свой пост. Как мы видим, они абсолютно одинаковы.   -  person siimval    schedule 28.04.2017
comment
Есть ли способ увидеть, как выглядят сопоставления ES? меня это больше интересует   -  person Val    schedule 28.04.2017
comment
О Конечно. Глупый я, должен был понять. Я обновлю свой пост прямо сейчас.   -  person siimval    schedule 28.04.2017
comment
Я обновил сообщение сейчас и добавил сопоставление ElasticSearch. Я извлек сопоставления, начинающиеся с c, потому что то, что идет раньше, не имеет значения.   -  person siimval    schedule 28.04.2017


Ответы (1)


Я предлагаю использовать match_phrase вместо match. Запрос match_phrase проанализирует ввод, если для запрашиваемого поля определены анализаторы, и найдет документы, соответствующие следующим критериям:

  • все термины должны появиться в поле
  • они должны иметь тот же порядок, что и входное значение
person Etibar - a tea bar    schedule 02.05.2017
comment
Благодарю вас! Теперь это работает. Так что проблема была в другом, а не в маппингах. - person siimval; 02.05.2017