2017-09-11 5 views
0

J'ai actuellement un objet imbriqué interest_scores dans ES qui ressemble à ceci:ElasticSearch - en utilisant la valeur d'objets imbriquées dans la fonction Score

[{ 
    username: 'Somebody', 
    interest_scores: [ 
     { name: 'Running', score: 10 } 
     { name: 'Food and drinks', score: 21 } 
    ] 
}, 
{ 
    username: 'SomebodyElse', 
    interest_scores: [ 
     { name: 'Running', score: 7 } 
     { name: 'Food and drinks', score: 29 } 
    ] 
}] 

Quand je saisissiez le terme de recherche Courir Je voudrais à l'utilisateur le plus élevé score pour Exécution pour être retourné en premier.

Je sais que la façon de faire est d'utiliser un Function Score Query mais je ne suis pas sûr de savoir comment utiliser le terme de recherche correspondant dans la fonction/script. Ce que je pense est que la requête retournera tous les documents qui ont l'intérêt "Running" et puis je pourrais utiliser quelque chose comme interest_scores.{match}.score pour ajouter ou multiplier par le score du document.

Une aide avec ceci serait grandement appréciée!

Comme demandé, voici la mise en correspondance:

{ 
 
    "influencers": { 
 
    "mappings": { 
 
     "influencer": { 
 
     "properties": { 
 
      "email": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      }, 
 
      "gender": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      }, 
 
      "geo": { 
 
      "type": "geo_point" 
 
      }, 
 
      "hashtags": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      }, 
 
      "id": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      }, 
 
      "interest_scores": { 
 
      "type": "nested", 
 
      "properties": { 
 
       "name": { 
 
       "type": "text", 
 
       "fields": { 
 
        "keyword": { 
 
        "type": "keyword", 
 
        "ignore_above": 256 
 
        } 
 
       } 
 
       }, 
 
       "score": { 
 
       "type": "long" 
 
       } 
 
      } 
 
      }, 
 
      "interests": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      }, 
 
      "language": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      }, 
 
      "location": { 
 
      "properties": { 
 
       "city": { 
 
       "type": "text", 
 
       "fields": { 
 
        "keyword": { 
 
        "type": "keyword", 
 
        "ignore_above": 256 
 
        } 
 
       } 
 
       }, 
 
       "country": { 
 
       "type": "text", 
 
       "fields": { 
 
        "keyword": { 
 
        "type": "keyword", 
 
        "ignore_above": 256 
 
        } 
 
       } 
 
       }, 
 
       "country_code": { 
 
       "type": "text", 
 
       "fields": { 
 
        "keyword": { 
 
        "type": "keyword", 
 
        "ignore_above": 256 
 
        } 
 
       } 
 
       }, 
 
       "lat": { 
 
       "type": "float" 
 
       }, 
 
       "lng": { 
 
       "type": "float" 
 
       }, 
 
       "state_code": { 
 
       "type": "text", 
 
       "fields": { 
 
        "keyword": { 
 
        "type": "keyword", 
 
        "ignore_above": 256 
 
        } 
 
       } 
 
       }, 
 
       "subdivision": { 
 
       "type": "text", 
 
       "fields": { 
 
        "keyword": { 
 
        "type": "keyword", 
 
        "ignore_above": 256 
 
        } 
 
       } 
 
       } 
 
      } 
 
      }, 
 
      "network_data": { 
 
      "properties": { 
 
       "facebook": { 
 
       "properties": { 
 
        "url": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "username": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        } 
 
       } 
 
       }, 
 
       "instagram": { 
 
       "properties": { 
 
        "bio": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "engagement": { 
 
        "type": "float" 
 
        }, 
 
        "id": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "picture": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "reach": { 
 
        "type": "long" 
 
        }, 
 
        "url": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "username": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        } 
 
       } 
 
       }, 
 
       "pinterest": { 
 
       "properties": { 
 
        "url": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "username": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        } 
 
       } 
 
       }, 
 
       "twitter": { 
 
       "properties": { 
 
        "bio": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "engagement": { 
 
        "type": "float" 
 
        }, 
 
        "id": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "picture": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "reach": { 
 
        "type": "long" 
 
        }, 
 
        "url": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "username": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        } 
 
       } 
 
       }, 
 
       "youtube": { 
 
       "properties": { 
 
        "bio": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "engagement": { 
 
        "type": "float" 
 
        }, 
 
        "id": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "picture": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "reach": { 
 
        "type": "long" 
 
        }, 
 
        "url": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "username": { 
 
        "type": "text", 
 
        "fields": { 
 
         "keyword": { 
 
         "type": "keyword", 
 
         "ignore_above": 256 
 
         } 
 
        } 
 
        }, 
 
        "videos": { 
 
        "type": "long" 
 
        }, 
 
        "views": { 
 
        "type": "long" 
 
        }, 
 
        "views_per_video": { 
 
        "type": "float" 
 
        } 
 
       } 
 
       } 
 
      } 
 
      }, 
 
      "networks": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      }, 
 
      "picture": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      }, 
 
      "total_reach": { 
 
      "type": "long" 
 
      }, 
 
      "username": { 
 
      "type": "text", 
 
      "fields": { 
 
       "keyword": { 
 
       "type": "keyword", 
 
       "ignore_above": 256 
 
       } 
 
      } 
 
      } 
 
     } 
 
     } 
 
    } 
 
    } 
 
}

Je n'ai pas une requête de score de fonction encore, je teste que dans les outils de développement de Kibana - J'ai tout des autres filtres fonctionnent correctement cependant. Je suis à la recherche de dire « Si le terme de recherche correspond à un interest_scores.name trier puis les coups par la interest_scores.score de cette interest_scores.name

Mise à jour

Ce qui suit semble fonctionner quand je le tester dans les outils Kibana dev:

{ 
 
    "query": { 
 
    "nested": { 
 
     "path": "interest_scores", 
 
     "score_mode": "sum", 
 
     "query": { 
 
     "function_score": { 
 
      "query": { 
 
       "match": { "interest_scores.name": "Running" } 
 
      }, 
 
      "script_score": { 
 
      "script": "_score + doc['interest_scores.score'].value" 
 
      } 
 
     } 
 
     } 
 
    } 
 
    } 
 
}

Je l'ai testé avec quelques différentes mer rch termes et il retourne toujours le meilleur score en premier, mais ce qui est étrange, c'est que je reçois les mêmes résultats lorsque je supprime la fonction script_score. Quelqu'un peut-il me dire si c'est une bonne solution, ou pourquoi cela fonctionne sans le script_score?

+0

Pouvez-vous ajouter votre mappage et la requête que vous avez utilisée? – Eli

Répondre

0

Comme décrit here, vous pouvez trier par champs imbriqués:

{ 
    "_source": false, # for inner hits - you can remove it 
    "query": { 
    "nested": { 
     "path": "interest_scores", 
     "filter": { 
     "range": { 
      "interest_scores.score": { 
      "gte": "0" 
      } 
     } 
     }, 
     "inner_hits": {} # for inner hits - you can remove it 
    } 
    }, 
    "sort": { 
    "interest_scores.score": { 
     "order": "desc", 
     "mode": "max", 
     "nested_filter": { 
     "range": { 
      "interest_scores.score": { 
      "gte": "0" 
      } 
     } 
     } 
    } 
    } 
} 

* Faites attention, vous pouvez utiliser la capacité inner_hits pour afficher uniquement les documents pertinents imbriqués. Si tous les documents internes sont pertinents, veuillez supprimer les lignes marquées.

** Utilisez le filtre sur le champ score ou sur tout autre champ (par exemple: name vous souhaitez filtrer par).

EDIT 1: Si vous voulez obtenir les scores de nom spécifique triés, essayez:

{ 
    "_source": false, 
    "query": { 
    "nested": { 
     "path": "interest_scores", 
     "filter": { 
     "term": { 
      "interest_scores.name": "SCORE_NAME" 
     } 
     }, 
     "inner_hits": {} 
    } 
    }, 
    "sort": { 
    "interest_scores.score": { 
     "order": "desc", 
     "mode": "max", 
     "nested_filter": { 
     "range": { 
      "interest_scores.score": { 
      "gte": "0" 
      } 
     } 
     } 
    } 
    } 
} 

Mettez le nom du score au lieu désiré SCORE_NAME.

+0

Merci pour l'information, j'ai lu les docs sur le tri des champs imbriqués - mais comment puis-je dire à Elasticsearch de trier par le 'intérêt_scores.score' pour un 'interest_scores.name' spécifique? Je veux dire à ES "Si ce mot/cette phrase est trouvé dans' interest_scores.name' alors triez par ce 'interest_scores.score'. – ryantbrown

+0

J'ai mis à jour ma réponse – Eli