ElasticSearch post_filter и отфильтрованные агрегаты не ведут себя одинаково - PullRequest
0 голосов
/ 21 декабря 2018

Я потратил целую неделю на это без надежды решить это.Я слежу за этой (довольно старой) статьей о поиске в электронной коммерции и многогранной фильтрации и т. Д., И до сих пор она работает хорошо (результаты поиска отличные, а агрегаты отлично работают при применении фильтров INзапрос. Я использую ElasticSearch 6.1.1.

Но так как я хочу, чтобы мои пользователи могли выполнять множественный выбор фасетов, я переместил фильтры в раздел post_filter. Этот по-прежнему работает, он корректно фильтрует результаты и показывает точные значения агрегации для всего набора документов.

После прочтения этого вопроса в StackOverflow я понял, что должен выполнитькакая-то сумасшедшая акробатика с «отфильтрованными» агрегациями наряду со «специальными» агрегациями для взаимной обрезки агрегаций с целью отображения правильных подсчетов и одновременного использования нескольких фильтров с ними. Я попросил дать некоторые пояснения по этому вопросу, но ответа пока нет (это старый вопрос).

Проблема, с которой я столкнулсяТак долго пытались получить набор отфильтрованных агрегатов для вложенных полей , где ВСЕ фасеты фильтруются всеми фильтрами.

Мой план состоит в том, чтобы использовать общие агрегации (нефильтрованные) и оставить неагрегированные агрегации выбранного фасета (чтобы я мог выбрать несколько записей), но отфильтровать все ДРУГИЕ агрегации с выбранными в данный момент фасетами, чтобы я мог толькоотобразите фильтры, которые я все еще могу применить.

Однако, если я использую тот же фильтр на документах (которые работают нормально) и помещаю фильтр в отфильтрованные агрегаты, они не работают должным образом.Все счета неверны.Мне известно, что агрегаты вычисляются до фильтров, поэтому я реплицирую фильтры на агрегаты, которые мне нужны.

Вот мой запрос:

  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "fields": [
              "search_data.full_text_boosted^7",
              "search_data.full_text^2"
            ],
            "type": "cross_fields",
            "analyzer": "full_text_search_analyzer",
            "query": "some book"
          }
        }
      ]
    }
  }

Ничего особенного, он прекрасно работает и возвращает релевантные результаты.

А вот мой фильтр (в post_filter):

"post_filter" : {
    "bool" : {
      "must" : [
      {
        "nested": {
          "path": "string_facets",
            "query": {
              "bool" : {
                "filter" : 
                [
                  { "term" : { "string_facets.facet_name" : "Cover colour" } },
                  { "terms" : { "string_facets.facet_value" : [ "Green" ] } }
                ]
              }
            }
          }
        }

      ]
    }
  }

Позвольте мне подчеркнуть: это работает FINE .Я вижу правильные результаты (в этом случае отображаются результаты «13», все из которых соответствуют правильному полю - «Цвет обложки» = «Зеленый»).

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

    "agg_string_facets": {
  "nested": {
    "path": "string_facets"
  },
  "aggregations": {
      "facet_name": {
        "terms": {
          "field": "string_facets.facet_name"
        },
        "aggregations": {
          "facet_value": {
            "terms": {
              "field": "string_facets.facet_value"
            }
          }
        }
      }
  }
}

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

Теперь проверьте это: я создаю агрегацию для тех же вложенных полей, но отфильтрованных, чтобы я мог получить агрегаты + фасетыкоторые «выживают» мой фильтр:

"agg_all_facets_filtered" : {

           "filter" : {
             "bool" : {
               "must" : [
                {
                   "nested": {
                     "path": "string_facets",
                     "query": {
                       "bool" : {
                         "filter" : [
                           { "term" : { "string_facets.facet_name" : "Cover colour" } },
                           { "terms" : { "string_facets.facet_value" : [ "Green" ] } }
                          ]
                       }
                    }
                  }
              }]
            }
        },
        "aggs" : {
         "agg_all_facets_filtered" : {
           "nested": { "path": "string_facets" },
           "aggregations": {
            "facet_name": {
              "terms": { "field": "string_facets.facet_name" },
              "aggregations": {
                    "facet_value": {
                      "terms": { "field": "string_facets.facet_value" }
                    }
                  }
                }
            }  
         }

       }

Обратите внимание, что фильтр, который я использую для этого агрегата, такой же, как и фильтр, который фильтрует мои результаты в первую очередь (в посте).

Но по какой-то причине все возвращенные агрегации неверны, а именно - количество фасетов.Например, в моем поиске здесь я получаю 13 результатов, но агрегация, возвращенная из ' agg_all_facets_filtered ', имеет только счет: 'Cover color' = 4 .

{
  "key": "Cover colour",
  "doc_count": 4,
  "facet_value": {
    "doc_count_error_upper_bound": 0,
    "sum_other_doc_count": 0,
    "buckets": [
        {
          "key": "Green",
          "doc_count": 4
        }
    ]
  }
}

После проверки, почему 4, я заметил, что 3 документа содержат фасет ' Цвет обложки ' дважды: один раз для 'Зеленого' и один раз для 'Некоторые другие цвета' ... такПохоже, мои агрегаты учитывают только те записи, которые имеют это имя ДВАЖДЫ - или имеют его вместе с другими документами.Вот почему я считаю, что мой фильтр агрегации неправильный.Я много читал на «И» против «ИЛИ» соответствующих / фильтров, я пытался с «Фильтром», «Должен» и т. Д. Ничто не исправляет это.

Извините, это был длинный вопросно:

КАК я могу написать фильтр агрегации, чтобы возвращаемые фасеты имели правильное число, учитывая тот факт, что мой фильтр отлично работает сам по себе?

Спасибовсе очень понравилось.

ОБНОВЛЕНИЕ: После запроса, например, вот мой полный запрос (обратите внимание на фильтры в post_filter, а также на тот же фильтр в отфильтрованных агрегатах):

{
  "size" : 0,
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "fields": [
              "search_data.full_text_boosted^7",
              "search_data.full_text^2"
            ],
            "type": "cross_fields",
            "analyzer": "full_text_search_analyzer",
            "query": "bible"
          }
        }
      ]
    }
  },

  "post_filter" : {

    "bool" : {
      "must" : [
      {
        "nested": {
          "path": "string_facets",
            "query": {
              "bool" : {
                "filter" : 
                [
                  { "term" : { "string_facets.facet_name" : "Cover colour" } },
                  { "terms" : { "string_facets.facet_value" : [ "Green" ] } }
                ]
              }
            }
          }
        }

      ]
    }

  },

  "aggregations": {

        "agg_string_facets": {
      "nested": {
        "path": "string_facets"
      },
      "aggregations": {
          "facet_name": {
            "terms": {
              "field": "string_facets.facet_name"
            },
            "aggregations": {
              "facet_value": {
                "terms": {
                  "field": "string_facets.facet_value"
                }
              }
            }
          }
      }
    },

    "agg_all_facets_filtered" : {

           "filter" : {
             "bool" : {
               "must" : [
                {
                   "nested": {
                     "path": "string_facets",
                     "query": {
                       "bool" : {
                         "filter" : [
                           { "term" : { "string_facets.facet_name" : "Cover colour" } },
                           { "terms" : { "string_facets.facet_value" : [ "Green" ] } }
                          ]
                       }
                    }
                  }
              }]
            }
        },
        "aggs" : {
         "agg_all_facets_filtered" : {
           "nested": { "path": "string_facets" },
           "aggregations": {
            "facet_name": {
              "terms": { "field": "string_facets.facet_name" },
              "aggregations": {
                    "facet_value": {
                      "terms": { "field": "string_facets.facet_value" }
                    }
                  }
                }
            }  
         }

       }


    }

  }
}

Возвращенные результаты верны (какнасколько далеко идут документы) и вот агрегация (нефильтрованная, по результатам, для 'agg_string_facets' - уведомление "Зеленый" показывает 13 документов - это правильно):

{
            "key": "Cover colour",
            "doc_count": 483,
            "facet_value": {
              "doc_count_error_upper_bound": 0,
              "sum_other_doc_count": 111,
              "buckets": [
                {
                  "key": "Black",
                  "doc_count": 87
                },
                {
                  "key": "Brown",
                  "doc_count": 75
                },
                {
                  "key": "Blue",
                  "doc_count": 45
                },
                {
                  "key": "Burgundy",
                  "doc_count": 43
                },
                {
                  "key": "Pink",
                  "doc_count": 30
                },
                {
                  "key": "Teal",
                  "doc_count": 27
                },
                {
                  "key": "Tan",
                  "doc_count": 20
                },
                {
                  "key": "White",
                  "doc_count": 18
                },
                {
                  "key": "Chocolate",
                  "doc_count": 14
                },
                {
                  "key": "Green",
                  "doc_count": 13
                }
              ]
            }
          }

А вот агрегация (отфильтровано с помощью того же фильтра, в то же время из 'agg_all_facets_filtered'), отображая только 4 для "зеленого":

{
              "key": "Cover colour",
              "doc_count": 4,
              "facet_value": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 0,
                "buckets": [
                  {
                    "key": "Green",
                    "doc_count": 4
                  }
                ]
              }
            }

ОБНОВЛЕНИЕ 2: Вот несколько примеров документов, возвращаемых запросом:

"hits": {
    "total": 13,
    "max_score": 17.478987,
    "hits": [
      {
        "_index": "redacted",
        "_type": "product",
        "_id": "33107",
        "_score": 17.478987,
        "_source": {
          "type": "product",
          "document_id": 33107,
          "search_data": {
            "full_text": "hcsb compact ultrathin bible mint green leathertouch  holman bible staff leather binding 9781433617751 ",
            "full_text_boosted": "HCSB Compact Ultrathin Bible Mint Green Leathertouch Holman Bible Staff "
          },
          "search_result_data": {
            "name": "HCSB Compact Ultrathin Bible, Mint Green Leathertouch (Leather)",
            "preview_image": "/images/products/medium/0.jpg",
            "url": "/Products/ViewOne.aspx?ProductId=33107"
          },
          "string_facets": [
            {
              "facet_name": "Binding",
              "facet_value": "Leather"
            },
            {
              "facet_name": "Bible size",
              "facet_value": "Compact"
            },
            {
              "facet_name": "Bible size",
              "facet_value": "Ultrathin"
            },
            {
              "facet_name": "Bible version",
              "facet_value": "HCSB"
            },
            {
              "facet_name": "Cover colour",
              "facet_value": "Green"
            }
          ]
        }
      },
      {
        "_index": "redacted",
        "_type": "product",
        "_id": "17240",
        "_score": 17.416323,
        "_source": {
          "type": "product",
          "document_id": 17240,
          "search_data": {
            "full_text": "kjv thinline bible compact  leather binding 9780310439189 ",
            "full_text_boosted": "KJV Thinline Bible Compact "
          },
          "search_result_data": {
            "name": "KJV Thinline Bible, Compact (Leather)",
            "preview_image": "/images/products/medium/17240.jpg",
            "url": "/Products/ViewOne.aspx?ProductId=17240"
          },
          "string_facets": [
            {
              "facet_name": "Binding",
              "facet_value": "Leather"
            },
            {
              "facet_name": "Bible size",
              "facet_value": "Compact"
            },
            {
              "facet_name": "Bible size",
              "facet_value": "Thinline"
            },
            {
              "facet_name": "Bible version",
              "facet_value": "KJV"
            },
            {
              "facet_name": "Cover colour",
              "facet_value": "Green"
            }
          ]
        }
      },
      {
        "_index": "redacted",
        "_type": "product",
        "_id": "17243",
        "_score": 17.416323,
        "_source": {
          "type": "product",
          "document_id": 17243,
          "search_data": {
            "full_text": "kjv busy mom's bible  leather binding 9780310439134 ",
            "full_text_boosted": "KJV Busy Mom'S Bible "
          },
          "search_result_data": {
            "name": "KJV Busy Mom's Bible (Leather)",
            "preview_image": "/images/products/medium/17243.jpg",
            "url": "/Products/ViewOne.aspx?ProductId=17243"
          },
          "string_facets": [
            {
              "facet_name": "Binding",
              "facet_value": "Leather"
            },
            {
              "facet_name": "Bible size",
              "facet_value": "Pocket"
            },
            {
              "facet_name": "Bible size",
              "facet_value": "Thinline"
            },
            {
              "facet_name": "Bible version",
              "facet_value": "KJV"
            },
            {
              "facet_name": "Cover colour",
              "facet_value": "Pink"
            },
            {
              "facet_name": "Cover colour",
              "facet_value": "Green"
            }
          ]
        }
      },
      {
        "_index": "redacted",
        "_type": "product",
        "_id": "33030",
        "_score": 15.674053,
        "_source": {
          "type": "product",
          "document_id": 33030,
          "search_data": {
            "full_text": "apologetics study bible for students grass green leathertou  mcdowell sean; holman bible s leather binding 9781433617720 ",
            "full_text_boosted": "Apologetics Study Bible For Students Grass Green Leathertou Mcdowell Sean; Holman Bible S"
          },
          "search_result_data": {
            "name": "Apologetics Study Bible For Students, Grass Green Leathertou (Leather)",
            "preview_image": "/images/products/medium/33030.jpg",
            "url": "/Products/ViewOne.aspx?ProductId=33030"
          },
          "string_facets": [
            {
              "facet_name": "Binding",
              "facet_value": "Leather"
            },
            {
              "facet_name": "Bible designation",
              "facet_value": "Study Bible"
            },
            {
              "facet_name": "Bible designation",
              "facet_value": "Students"
            },
            {
              "facet_name": "Bible feature",
              "facet_value": "Indexed"
            },
            {
              "facet_name": "Cover colour",
              "facet_value": "Green"
            }
          ]
        }
      },
      {
        "_index": "redacted",
        "_type": "product",
        "_id": "33497",
        "_score": 15.674053,
        "_source": {
          "type": "product",
          "document_id": 33497,
          "search_data": {
            "full_text": "hcsb life essentials study bible brown / green  getz gene a.; holman bible st imitation leather 9781586400446 ",
            "full_text_boosted": "HCSB Life Essentials Study Bible Brown  Green Getz Gene A ; Holman Bible St"
          },
          "search_result_data": {
            "name": "HCSB Life Essentials Study Bible Brown / Green (Imitation Leather)",
            "preview_image": "/images/products/medium/33497.jpg",
            "url": "/Products/ViewOne.aspx?ProductId=33497"
          },
          "string_facets": [
            {
              "facet_name": "Binding",
              "facet_value": "Imitation Leather"
            },
            {
              "facet_name": "Bible designation",
              "facet_value": "Study Bible"
            },
            {
              "facet_name": "Bible version",
              "facet_value": "HCSB"
            },
            {
              "facet_name": "Binding",
              "facet_value": "Imitation leather"
            },
            {
              "facet_name": "Cover colour",
              "facet_value": "Brown"
            },
            {
              "facet_name": "Cover colour",
              "facet_value": "Green"
            }
          ]
        }
      }
}

1 Ответ

0 голосов
/ 03 января 2019

Тайна раскрыта!Спасибо за ваш вклад, оказалось, что в версии, которую я использовал (6.1.1), была ошибка.Я не знаю, в чем именно заключается ошибка, но я установил ElasticSearch 6.5, переиндексировал свои данные и без изменений в запросах или сопоставлениях, все работает как надо!

Теперь я нене знаю, должен ли я отправить отчет об ошибке в ES или просто оставить его, видя, что это более старая версия, и они ушли.

...