2014-08-31 7 views
2

Donc, mon application Rails utilisant elasticsearch (avec searchkick), fonctionne très bien avec la fonction de commande _geo_distance, mais j'ai besoin de faire une commande plus complexe qui inclut l'emplacement ET une tentative pour promouvoir un nom de l'entreprise exacte chaîne de correspondance. Par exemple, si je fais une requête et qu'il y a 10 résultats de distance ascendante, mais le résultat # 5 est aussi une correspondance de chaîne exacte sur le nom de l'entreprise dans l'enregistrement, je voudrais promouvoir/élever cela à la Position n ° 1 (essentiellement en remplaçant le tri à distance pour cet enregistrement).Rails elasticsearch _geo_distance et scoring/tri personnalisé

Il y a deux façons que je peux voir pour essayer de résoudre ce problème, mais je rencontre des problèmes avec les deux. Tout d'abord, serait de le faire sur la requête initiale, afin que elasticsearch gère le travail. Deuxièmement, serait de faire un certain type de re-tri post-processus sur le résultat retourné par elasticsearch pour rechercher une correspondance exacte et ré-ordonner si nécessaire. Le problème avec la première méthode est que les mécanismes de scoring intégrés semblent se déplacer complètement à distance en invoquant _geo_distance, me laissant me demander comment mélanger les fonctions de scoring personnalisées avec l'emplacement. Le problème avec la seconde méthode est que les résultats de la recherche retournés sont un type personnalisé de l'objet SearchKick qui ne semble pas aimer les mécanismes de tri de tableau ou de hachage normaux pour un post-traitement.

Existe-t-il un moyen de faire quelque chose avant ou après une requête pour promouvoir un document dans les résultats de cette manière?

Merci.

Répondre

1

En fait, il existe plusieurs façons de «contrôler» la notation. Avant d'indexer, si vous avez déjà un document est destiné à obtenir un score élevé/boost. Vous pouvez donner un score élevé pour le document spécial avant l'indexation, s'il vous plaît référence here.

Si vous ne pouvez pas déterminer le boost avant l'indexation, vous pouvez le booster dans la commande query. À propos de la requête boosting, il y a aussi beaucoup d'options et cela dépend de la requête que vous avez utilisée.

Pour la requête de chaîne de requête:

Vous pouvez stimuler certains domaines, tels que fields" : ["content", "name.*^5"], ou stimuler une commande de requête tels que, quick^2 fox (cela pourrait fonctionner pour vous, coup de pouce supplémentaire le nom).

Pour d'autres:

Vous pouvez donner coup de pouce pour la requête à long terme, comme le renforcement de l'affaire « ivan »:

"term" : {"name" : {"value" : "ivan","boost" : 10.0}}

vous pouvez envelopper dans la requête bool et stimuler le choix Cas. ex. trouver tout 'ivan', booster 'ji' sur le champ de nom.

{ "requête": { "bool": { "must": [{ "match": { "name": "ivan"}}],
"devrait": [{ "terme" : { "name": { "valeur": "ji", "boost": 10}}}]}}}

Sauf pour la requête à long terme, il y a beaucoup de requêtes qui prennent en charge boost, comme prefix requête, match requête. Vous pouvez l'utiliser dans des situations. Voici quelques exemples officiels: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/_boosting_query_clauses.html

La stimulation peut ne pas être facile pour contrôler le score, car elle nécessite une normalisation. Vous pouvez spécifier le score en utilisant la requête function_score pour spécifier le score direct: C'est vraiment une requête utile si vous avez besoin de plus de contrôle direct.


En bref, vous pouvez envelopper votre requête dans bool et ajouter un peu de coup de pouce pour la mise en correspondance de nom, comme suit:

{ "query" : { 
    "bool" : { 
    "must": [ 
      {"filtered" : { 
      "filter" : { 
       "geo_distance" : { 
        "distance" : "2000km", 
        "loc" : { 
         "lat" : 10, 
         "lon" : 10 
        } 
       } 
      } 
     }}], 
    "should" : [ { "term" : { "name": { "value" : "ivan", "boost" : 10 }}}]}}, 
"sort" : [ 
      "_score", 
    { 
     "_geo_distance" : { 
      "loc" : [10, 10], 
      "order" : "asc", 
      "unit" : "km", 
      "mode" : "min", 
      "distance_type" : "sloppy_arc" 
     } 
    } 
] 
} 

Pour plus de détails, vous pouvez consulter mon essentiel https://gist.github.com/hxuanji/e5acd9a5174ea10c08b8. Je boost le nom "ivan". En résultat, le document "ivan" devient le premier plutôt que le document (10,10).

+1

Merci pour votre réponse, mais je ne suis toujours pas clair sur la façon dont cette notation fonctionnerait avec les scores de distance Geo/résultats. Les résultats Geo sont triés par distance, ce qui semble modifier les fonctions de notation normales. Dans un tel cas, une augmentation du "score" conduirait à une mesure de distance incorrecte. Comment puis-je conserver les mesures Geo, et toujours promouvoir le document? – kayatela

+0

Je suppose qu'une autre façon d'aborder cela serait d'avoir les résultats triés par _score (pas de géo), mais aussi d'inclure les données _geo_distance dans les résultats retournés. Mais je n'ai pas compris comment faire ça non plus. – kayatela

+0

vérifier mon édition ci-dessus, je vous ai donné un exemple. – hxuanji

Questions connexes