Select où 2 champs doivent avoir la même valeur


(Athimue) #1

Bonjour à tous,

Comme mon titre l'explique, je souhaite ferme une requête Select qui me récupère les documents où 2 colonnes ont la même valeur.
En effet, j'ai essayé via :

GET index/doc/_search
{ 
    "query": {
      "match": {
        "colonne1": "colonne2"
      }
    }
} 

mais cela va me recupére les documents où colonne1 a pour valeur colonne2. Et moi je souhaite récupérer les documents où la valeur de colonne1 et colonne2 est identique.
Je suis nouveau, je n'ai pas trouvé de réponse à mon problème, veuillez m'excuser si ma question est facile.

Cordialement,

Athimue


(David Pilato) #2

Tu ne peux pas faire ça simplement dans elasticsearch ou en tout cas de façon efficace (rapidité).

Une précision : tu veux vérifier à l'intérieur du même document si les 2 champs sont égaux, c'est ça ?


(Athimue) #3

Merci

Je voudrais récupérer tous les documents qui ont leurs 2 champs identiques.

Il n'existe aucune solution simple ?

En SQL, cela s'écrit simplement :

WHERE colonne1=colonne2


(David Pilato) #4

Il n'existe aucune solution simple ?

Non. Tu peux utiliser des scripts (voir https://www.elastic.co/guide/en/elasticsearch/reference/6.3/modules-scripting-using.html) mais ça sera sans doute super lent car ( https://www.elastic.co/guide/en/elasticsearch/reference/6.3/modules-scripting-fields.html#_search_and_aggregation_scripts ):

With the exception of script fields which are executed once per search hit, scripts used in search and aggregations will be executed once for every document which might match a query or an aggregation. Depending on how many documents you have, this could mean millions or billions of executions: these scripts need to be fast!

L'idéal est de calculer ça au moment de l'indexation. Avec un script ou pas. En tout cas ça sera plus rapide ensuite à la recherche.


(Athimue) #5

D'accord, merci pour ta réponse, je vais quand même regarder au niveau des scripts.

Aurais-tu par hasard une idée de comment le réaliser ? sans doute avec doc['colonne1'] mais je ne comprends comment je pourrais faire comprendre au script que doc['colonne1']=doc['colonne2']


(David Pilato) #6

En fait, je pense que ce n'est pas vraiment possible.
Car les scripted fields sont calculés après exécution de la requête et non avant.

Donc tu ne peux pas créer un champ booléen genre isEqual sur lequel tu pourrais ensuite faire un filtre.

Je ne vois pas de solution. Encore une fois, le mieux est de calculer ça au moment de l'indexation.


(Athimue) #7

Ok, merci pour tes réponses, je vais fouiller de mon coté


(Gabriel Tessier) #8

Bonjour,

Juste une autre facon de faire mais vraiment spécifique, si t'as pas besoin de requeter en temps réel et t'utilises des données dont tu connais déjà le mapping que t'as définie dans un template.
Tu peux utiliser "_reindex" pour mettre à jour les documents avec ta condition, un exemple en dessous:

deux documents dont un à le champ name == name_common

POST user_data/doc/
{
"name": "Party",
"name_common": "Party"
}

POST user_data/doc/
{
"name": "Party",
"name_common": "Patrol"
}

POST _reindex
{
"source": {
"index": "user_data"
},
"dest": {
"index": "user_data_equal",
"version_type": "external"
},
"script": {
"source": "if (ctx._source.name == ctx._source.name_common) {ctx._source.is_equal = 1}",
"lang": "painless"
}
}

Si tu regardes dans l'index user_data_equal t'auras tes documents recopié avec dans le premier document la colonne is_equal. Y'a meme moyen de faire plus compliqué suivant tes besoins en utilisant ingest.... :grinning:

Le mieux et le plus simple c'est comme dit David, c'est de le faire à l'indexation mais si t'as déjà tes données et tu peux pas les modifier avant d'indexer.
Ca fait plein de si, mais dans un cas precis ca peux aider.


(Athimue) #9

Je te remercie pour ta réponse. En effet, cela répond à mes besoins, je vais continuer de fouiller de mon coté en utilisant ta méthode :grin:


(system) #10

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