web-dev-qa-db-fra.com

Elasticsearch comment utiliser multi_match avec un caractère générique

J'ai un objet Utilisateur avec les propriétés Nom et Prénom. Je souhaite rechercher ces champs à l'aide d'une seule requête et j'ai trouvé multi_match dans la documentation, mais je ne sais pas comment l'utiliser correctement avec un caractère générique. C'est possible?

J'ai essayé avec un multi_match requête mais cela n'a pas fonctionné:

{
    "query": {
        "multi_match": {
            "query": "*mar*",
            "fields": [
                "user.name",
                "user.surname"
            ]
        }
    }
}

Vous pouvez également utiliser un query_string requête avec caractères génériques.

"query": {
    "query_string": {
        "query": "*mar*",
        "fields": ["user.name", "user.surname"]
    }
}

Ce sera plus lent que d'utiliser un filtre nGram au moment de l'index (voir mon autre réponse), mais si vous cherchez une solution rapide et sale ...

De plus, je ne suis pas sûr de votre mappage, mais si vous utilisez user.name au lieu de name votre mappage doit ressembler à ceci:

"your_type_name_here": {
    "properties": {
        "user": {
            "type": "object",
            "properties": {
                "name": {
                    "type": "string"
                },
                "surname": {
                    "type": "string"
                }
            }
        }
    }
}
71
ramseykhalaf

Une telle requête a fonctionné pour moi:

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "bool": {
          "should": [
            {"query": {"wildcard": {"user.name": {"value": "*mar*"}}}},
            {"query": {"wildcard": {"user.surname": {"value": "*mar*"}}}}
          ]
        }
      }
    }
  }
}

Semblable à ce que vous faites, sauf que dans mon cas, il pourrait y avoir différents masques pour différents domaines.

17
Catherine Tsokur

Je viens de le faire maintenant:

GET _search {
    "query": {
        "bool": {
            "must": [
                {
                    "range": {
                        "theDate": {
                            "gte": "2014-01-01",
                            "lte": "2014-12-31"
                        }
                    }
                },
                {
                    "match" : {
                        "Country": "USA"
                    }
                }
            ],
            "should": [
                {
                    "wildcard" : { "Id_A" : "0*" }
                },
                {
                    "wildcard" : { "Id_B" : "0*" }
                }
            ],"minimum_number_should_match": 1
        }
    }
}
9
David Johnson

Je n'utiliserais pas de caractères génériques, cela ne s'adaptera pas bien. Vous demandez beaucoup au moteur de recherche au moment de la requête. Vous pouvez utiliser le filtre nGram pour effectuer le traitement à l'heure de l'index et non à la recherche.

Voir cette discussion sur le filtre nGram.

Après avoir indexé les name et surname correctement (changez votre mappage, il y a des exemples dans le lien ci-dessus), vous pouvez utiliser les correspondances multiples mais sans caractères génériques et obtenir les résultats attendus.

7
ramseykhalaf

Similaire à la suggestion ci-dessus, mais cela est simple et a fonctionné pour moi:

{
"query": {
    "bool": {
        "must":
        [
            {
                "wildcard" : { "processname.keyword" : "*system*" }
            },
            {
                "wildcard" : { "username" : "*admin*" }
            },
            {
                "wildcard" : { "device_name" : "*10*" }
            }
        ]
    }
}
}
1
JFletcher