web-dev-qa-db-fra.com

ElasticSearch post_filter et les agrégations filtrées ne se comportent pas de la même manière

J'ai passé une semaine entière sur ce sujet sans espoir de le résoudre. Je suis cet article (assez ancien) sur la recherche dans le commerce électronique et le filtrage par facettes , etc., et cela fonctionne bien jusqu'à présent (les résultats de la recherche sont excellents et les agrégations fonctionnent bien lorsque les filtres sont appliqués DANS la requête J'utilise ElasticSearch 6.1.1.

Mais comme je veux autoriser mes utilisateurs à effectuer plusieurs sélections sur les facettes, j'ai déplacé les filtres dans la section post_filter. Ceci fonctionne toujours bien, filtre correctement les résultats et affiche avec précision le nombre d'agrégations pour l'ensemble du document.

Après avoir lu cette question sur StackOverflow , je me suis rendu compte que je devais effectuer des acrobaties délirantes avec des agrégations "filtrées" aux côtés d'agrégations "spéciales" afin d'élaguer réciproquement les agrégations afin d'afficher des décomptes corrects ET d'autoriser plusieurs filtres. en même temps. J'ai demandé des éclaircissements sur cette question, mais pas encore de réponse (c'est une vieille question).

Le problème avec lequel je me bats depuis si longtemps est d'obtenir un ensemble d'agrégations filtrées sur champs imbriqués où TOUTES les facettes sont filtrées avec tous les filtres. 

Mon plan consiste à utiliser les agrégations générales (non filtrées) et à ne pas filtrer les agrégations de facettes sélectionnées (afin de pouvoir sélectionner plusieurs entrées), mais de filtrer toutes les autres agrégations avec les facettes actuellement sélectionnées, afin de ne pouvoir afficher que les filtres. appliquer.

Toutefois, si j'utilise le même filtre sur les documents (qui fonctionnent correctement) et que je le mets dans les agrégations filtrées, ils ne fonctionnent pas comme souhaité. Les comptes sont tous faux. Je suis conscient du fait que les agrégations sont calculées avant les filtres, c'est pourquoi je réplique les filtres sur les agrégations souhaitées. 

Voici ma requête:

  "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"
          }
        }
      ]
    }
  }

Rien de spécial ici, cela fonctionne très bien et renvoie des résultats pertinents. 

Et voici mon filtre (dans 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" ] } }
                ]
              }
            }
          }
        }

      ]
    }
  }

Permettez-moi de souligner: cela fonctionne bien. Je vois les résultats corrects (dans ce cas, les résultats '13' sont affichés, tous correspondant au champ correct - 'Couleur de la couverture' = 'Vert').

Voici mes général (agrégations non filtrées), qui renvoient toutes les facettes avec un nombre correct pour tous les produits:

    "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"
            }
          }
        }
      }
  }
}

_ {Cela aussi fonctionne parfaitement} _! Je vois toutes les agrégations avec un nombre de facettes précis pour tous les documents correspondant à ma requête.

Maintenant, vérifiez ceci: je crée une agrégation pour les mêmes champs imbriqués mais filtré afin de pouvoir obtenir les agrégations + les facettes qui "survivent" à mon filtre:

"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" }
                    }
                  }
                }
            }  
         }

       }

Veuillez noter que le filtre que j'utilise sur cette agrégation est identique à celui qui filtre mes résultats en premier lieu} _ (en post).

Mais pour une raison quelconque, les agrégations renvoyées sont toutes fausses, à savoir le nombre de facettes. Par exemple, dans ma recherche ici, j'obtiens 13 résultats, mais l'agrégation renvoyée par 'agg_all_facets_filtered' contient uniquement le nombre de: '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
        }
    ]
  }
}

Après avoir vérifié pourquoi 4, j'ai remarqué que 3 des documents contenaient deux fois la facette 'Couleur de couverture': une fois pour 'Vert' et une fois pour 'Quelques autres couleurs' ... il semble donc que mes agrégations ne comptent les entrées qui portent le nom de facette DEUX FOIS ou qui l’ont en commun avec d’autres documents. C'est pourquoi je pense que mon filtre sur l'agrégation est incorrect. J'ai beaucoup lu sur les ET et les OR des correspondances/filtres, j'ai essayé avec 'Filtre', 'Devrait', etc. Rien ne résout ce problème.

Je suis désolé c'est une longue question mais:

COMMENT puis-je écrire le filtre d'agrégation afin que les facettes retournées aient les comptes corrects, étant donné que mon filtre fonctionne parfaitement de manière autonome?} _

Merci beaucoup.

UPDATE: Suite à la demande par exemple, voici ma requête complète (veuillez noter les filtres dans post_filter ainsi que le même filtre dans les agrégations filtrées):

{
  "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" }
                    }
                  }
                }
            }  
         }

       }


    }

  }
}

Les résultats renvoyés sont corrects (pour ce qui est des documents) et voici l’agrégation (non filtrée, à partir des résultats, pour 'agg_string_facets' - la notification 'Green' indique 13 documents - ce qui est correct):

{
            "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
                }
              ]
            }
          }

Et voici l’agrégation (filtrée avec le même filtre, en même temps que 'agg_all_facets_filtered'), n’affichant que 4 pour 'Green':

{
              "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
                  }
                ]
              }
            }

UPDATE 2: Voici quelques exemples de documents renvoyés par la requête:

"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"
            }
          ]
        }
      }
}
6
Cristian Cotovan

Mystère résolu! Merci pour votre contribution, il s’avère que la version que j’utilisais (6.1.1) comportait un bogue. Je ne sais pas ce qu'est le bogue, mais j'ai installé ElasticSearch 6.5, réindexé mes données et sans modification des requêtes ni des mappages, tout fonctionne comme il se doit!

Maintenant, je ne sais pas si je devrais envoyer un rapport de bogue à ES ou le laisser, car c'est une version plus ancienne et ils sont passés à autre chose.

1
Cristian Cotovan