2017-09-26 5 views
0

私は弾性検索2を使用しています。私は場所の大きなデータベースを持っており、すべてgpsという属性を持っています。これはgeopointです。 私のフロントエンドアプリケーションは、クエリでフィルタリングされた結果を含むgoogle mapsコンポーネントを表示します。pizzaとしましょう。問題は、データセットが大きく成長し、クライアントがマップ上に結果を求めていることです。弾性検索 - 地図上に均等に分布する

ニューヨークで特定のクエリを検索すると、ニューヨーク全体で結果が得られますが、現在400の検索結果がマンハッタンの人口の多い地域で1つしかありません。

私の素朴なアプローチは、ちょうどこの結果は、マップ全体に広がることになることを保証するものではありません距離

{ 
    "size":400, 
    "query":{ 
     "bool":{ 
     "must":{ 
      "match_all":{ 

      } 
     }, 
     "filter":{ 
      "geo_distance":{ 
       "distance":"200km", 
       "gps":[ 
        -73.98502023369585, 
        40.76195656809083 
       ] 
      } 
     } 
     } 
    } 
} 

によってフィルタリングすることでした。 どうすればいいですか?

私はこの

{ 
    "size":400, 
    "query":{ 
     "bool":{ 
     "must":{ 
      "match_all":{ 

      } 
     }, 
     "filter":{ 
      "geo_distance":{ 
       "distance":"200km", 
       "gps":[ 
        -73.98502023369585, 
        40.76195656809083 
       ] 
      } 
     } 
     } 
    }, 
    "aggs":{ 
     "per_ring":{ 
     "geo_distance":{ 
      "field":"gps", 
      "unit":"km", 
      "origin":[ 
       -73.98502023369585, 
       40.76195656809083 
      ], 
      "ranges":[ 
       { 
        "from":0, 
        "to":100 
       }, 
       { 
        "from":100, 
        "to":200 
       } 
      ] 
     } 
     } 
    } 
} 

ためGeo-Distance Aggregationを使用して試してみたんだけど、結果リスト+バケットに属している要素の金額を受け取ります。結果リストは普及することが保証されていません。

"aggregations": { 
    "per_ring": { 
     "buckets": [ 
      { 
       "key": "*-100.0", 
       "from": 0, 
       "from_as_string": "0.0", 
       "to": 100, 
       "to_as_string": "100.0", 
       "doc_count": 33821 
      }, 
      { 
       "key": "100.0-200.0", 
       "from": 100, 
       "from_as_string": "100.0", 
       "to": 200, 
       "to_as_string": "200.0", 
       "doc_count": 6213 
      } 
     ] 
    } 
} 

私は1つのバケットの結果の半分、もう1つのバケットの半分を取りたいと思います。

私はまた、Geohash Grid Aggregationを使用しようとしましたが、それはまた、すべてのバケットの結果のサンプルを私に与えることはなく、その領域を提供するだけです。

したがって、1つの弾性検索クエリを使用してマップ全体に分散した結果の分布を取得するにはどうすればよいですか?

ありがとうございます!

+0

あなたのドキュメントの数ははるかにあなたが提供している400の限界を超えていますか?私は、指数のオーダーがあなたのスプレッドと何か関係があるのだろうかと思っています。なぜなら、距離に基づいてスコアリングをしていないと言うことができます。 – Miek

+0

ええ、私は約50万のオブジェクトを持っています。私は距離に基づいて得点を付けるべきですか? – tkcast

+0

私はあなたがそのようなことをすることができると思っています。おそらく、0〜100の範囲でクエリを実行し、次に101〜200などの範囲内の別のクエリを実行し、おおよそのディストリビューション目標に合ったサイズに制限します。おそらく複数の結果セットをマッピングしますか?私はこのアプローチを使用して配布の虚偽の表現に懸念を抱くだろう。 – Miek

答えて

0

ランダム性を導入することで、望ましい結果が得られるかもしれません。私は、あなたが同じディストリビューションのために同じディストリビューションを見ていると仮定しています(あなたは距離に基づいてスコアリングしていません。

{ 
    "size": 400, 
    "query": { 
    "function_score": { 
     "query": { 
     "bool": { 
      "must": [ 
      { 
       "match_all": {} 
      } 
      ], 
      "filter": { 
      "geo_distance": { 
       "distance": "200km", 
       "gps": [ 
       -73.98502023369585, 
       40.76195656809083 
       ] 
      } 
      } 
     } 
     }, 
     "functions": [ 
     { 
      "random_score": {} 
     } 
     ] 
    } 
    } 
} 

+1

これは素晴らしいアイデアです!それは私の問題を解決しました。どうもありがとうございました! – tkcast

+0

うれしいよ:) – Miek