web-dev-qa-db-fra.com

Recherche de chaînes de chaînes sur des éléments de tableau dans Elastic Search

J'essaie d'apprendre elasticsearch avec un exemple d'application simple, qui répertorie les citations associées à des personnes. L'exemple de mappage pourrait ressembler à:

{ 
  "people" : {
    "properties" : {
      "name" : { "type" : "string"},
      "quotations" : { "type" : "string" }
    }
  }
}

Quelques exemples de données pourraient ressembler à ceci: 

{ "name" : "Mr A",
  "quotations" : [ "quotation one, this and that and these"
                 , "quotation two, those and that"]
}

{ "name" : "Mr B",
  "quotations" : [ "quotation three, this and that"
                 , "quotation four, those and these"]
}

J'aimerais pouvoir utiliser l'API Querystring sur des citations individuelles et renvoyer les personnes qui correspondent. Par exemple, je pourrais vouloir trouver des personnes qui ont une citation qui contient (ceci ET ces) - qui devrait retourner "Monsieur A" mais pas "Monsieur B", etc. Comment puis-je atteindre cet objectif?

EDIT1:

La réponse ci-dessous d'Andrei semble fonctionner, les valeurs de données ressemblant maintenant à:

{"name":"Mr A","quotations":[{"value" : "quotation one, this and that and these"}, {"value" : "quotation two, those and that"}]}

Cependant, je n'arrive pas à obtenir une requête query_string au travail. Ce qui suit ne produit aucun résultat:

{
  "query": {
    "nested": {
      "path": "quotations",
      "query": {
        "query_string": {
            "default_field": "quotations",
            "query": "quotations.value:this AND these"
        }
      }
    }
  }
}

Existe-t-il un moyen de faire en sorte qu'une requête query_string fonctionne avec un objet imbriqué?

Edit2: Oui, voyez la réponse d'Andrei.

27
oneway

Pour que cette exigence soit remplie, vous devez examiner les objets imbriqués et non interroger une liste aplatie de valeurs, mais des valeurs individuelles issues de cet objet imbriqué. Par exemple:

{
  "mappings": {
    "people": {
      "properties": {
        "name": {
          "type": "string"
        },
        "quotations": {
          "type": "nested",
          "properties": {
            "value": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}

Valeurs:

{"name":"Mr A","quotations":[{"value": "quotation one, this and that and these"}, {"value": "quotation two, those and that"}]}
{"name":"Mr B","quotations":[{"value": "quotation three, this and that"}, {"value": "quotation four, those and these"}]}

Question:

{
  "query": {
    "nested": {
      "path": "quotations",
      "query": {
        "bool": {
          "must": [
            { "match": {"quotations.value": "this"}},
            { "match": {"quotations.value": "these"}}
          ]
        }
      }
    }
  }
}
31
Andrei Stefan

Malheureusement, il n’ya pas de bonne façon de le faire . http://www.elasticsearch.org/guide/fr/elasticsearch/guide/current/complex-core-fields.html

Lorsque vous récupérerez un document auprès d’Elasticsearch, tous les tableaux figureront dans dans le même ordre que lorsque vous avez indexé le document. Le champ _source que vous obtenez contient exactement le même document JSON que vous indexé.

Toutefois, les tableaux sont indexés - et peuvent être consultés - sous forme de champs à valeurs multiples, qui sont non ordonnés. Au moment de la recherche, vous ne pouvez pas vous référer à “le premier élément »ou« le dernier élément ». Pensez plutôt à un tableau comme un sac de valeurs.

En d'autres termes, il considère toujours toutes les valeurs du tableau.

Cela ne renverra que M. A

{
  "query": {
    "match": {
      "quotations": {
        "query": "quotation one",
        "operator": "AND"
      }
    }
  }
}

Mais cela rendra à la fois M. A et M. B:

{
  "query": {
    "match": {
      "quotations": {
        "query": "this these",
        "operator": "AND"
      }
    }
  }
}
6
evanwong

Si scripting est activé, cela devrait fonctionner:

"script": {
   "inline": "for(element in _source.quotations) { if(element == 'this' && element == 'these') {return true;} }; return false;"
 }
0
mjassani