Nested field and query/filter sur plusieurs champs en même temps


(Ugo Bourdon) #1

Bonjour,

Je dispose de données associant des identifiants quelconques à des zones géographiques et je veux pouvoir les requêter ensemble.

Voici le mapping que j'ai déduis de mon besoin :

 "zones": {
    "type": "nested",
    "properties": {
        "zone": {
            "type": "geo_shape",
            "tree": "quadtree",
            "precision": "1m"
        },
        "uids": {
            "type": "string",
            "index": "not_analyzed"
        }
    }
}

Je veux pouvoir requêter les critères zones.zone et zones.uids en même temps.
C'est à dire si j'ai un document qui contient une zones { zone: A_ZONE, uids: [1234,2345]} et une autre zones {zone: B_ZONE, uids: [6666]}
si je requête 1234 et B_ZONE je ne veux pas que ce document ressorte.

Il faudrait bien qu'il y ait un document avec la zones {zone: B_ZONE, uids: [1234,2345]} pour que ça match.

Mais je ne trouve pas comment faire cela ?
Quel type de requête dois-je faire ? Dois-je changer mon mapping ?


(David Pilato) #2

Qu'est ce que tu as essayé jusqu'à présent ?
Peux-tu fournir un script, le plus simple possible, qui permette de jouer avec un cas de test ?


(Ugo Bourdon) #3

Alors voici précisément ce que j'essai de faire :

Le mapping :

{
      "my_type" : {
        "properties" : {
          "interventionZones" : {
            "type" : "nested",
            "properties" : {
              "openingTicketPurposes" : {
                "type" : "string",
                "index" : "not_analyzed"
              },
              "zone" : {
                "type" : "geo_shape",
                "tree" : "quadtree",
                "tree_levels" : 20
              }
            }
          }
        }
      }
    }

Le document à la forme suivante :

{
  "uid" : "0b314e92-208d-4d82-8845-b7ec47f6a65e",
  "interventionZones" : [ {
    "openingTicketPurposes" : [ "7bd5b87e-b5de-4336-a861-be1af85cbc69" ],
    "zone" : {
      "type":"geometrycollection",
      "geometries" : [ {
        "type" : "circle",
        "coordinates" : [ 1, 0 ],
        "radius" : "100.0m"
      } ]
    }
  } ]
}

La requête :

{
  "from" : 0,
  "size" : 100,
  "query" : {
    "filtered" : {
      "query" : {
        "match_all" : { }
      },
      "filter" : {
        "bool" : {
          "must" : [ {
            "nested" : {
              "filter" : {
                "terms" : {
                  "interventionZones.openingTicketPurposes" : [ "0519cb57-8f8c-4d30-b490-7af880b21fbd" ]
                }
              },
              "path" : "interventionZones"
            }
          }, {
            "nested" : {
              "filter" : {
                "geo_shape" : {
                  "interventionZones.zone" : {
                    "shape" : {
                      "type" : "point",
                      "coordinates" : [ 1.0, 0.0 ]
                    },
                    "relation" : "intersects"
                  },
                  "_name" : null
                }
              },
              "path" : "interventionZones"
            }
          } ]
        }
      }
    }
  }
}

(David Pilato) #5

Tu sembles utiliser une vieille version, non ?

Peux-tu faire le même style de script sur la version 6.2 STP?
Le script idéal est le script qu'on peut copier-coller dans Kibana et simplement exécuter. Peux-tu faire ça ?


(Ugo Bourdon) #6

En effet j'utilise encore la version 1.7 :confused:

Je sais pas comment faire un script qui s'exécute sur Kibana.

Par contre j'ai trouvé une requête qui semble marcher avec cette forme :

{
  "from" : 0,
  "size" : 100,
  "query" : {
    "filtered" : {
      "query" : {
        "match_all" : { }
      },
      "filter" : {
        "bool" : {
          "must" : {
            "nested" : {
              "filter" : {
                "and" : {
                  "filters" : [ {
                    "terms" : {
                      "uid" : [ "93af5213-0aaa-41b1-a465-fb21de716e3c" ]
                    }
                  }, {
                    "terms" : {
                      "name" : [ "toto" ]
                    }
                  } ]
                }
              },
              "path" : "agencies"
            }
          }
        }
      }
    }
  },
  "sort" : [ {
    "expectedDate" : {
      "order" : "asc"
    }
  } ]
}

En gros si je comprends le principe, si je veux requêter plusieurs champs d'un objet nested et garder cette cohérence, il faut que je n'utilise qu'une seule occurence de nested.
J'avais aussi trouvé ça http://obtao.com/blog/2014/04/elasticsearch-recherche-avancee-nested/ mais j'arrive pas à refaire cette forme de requête avec le DSL scala (a.k.a Elastic4s) que j'utilise pour faire du Elasticsearch .


(David Pilato) #7

Aucune chance que je réinstalle une version 1.7 ou 2.4 sur mon laptop!

Un script Kibana, c'est quelque chose comme:

DELETE index
PUT index/_doc/1
{
  "foo": "bar"
}
GET index/_search
{
  "query": {
    "match": {
      "foo": "bar"
    }
  }
}

(system) #8

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.