2017-03-10 2 views
3

product_skusのインデックス内の特定のサプライヤの製品スキューを検索する販売インデックスに対して実行されている、特定のサプライヤIDのトップ100の販売者を生成する次のクエリがあります。これはうまくいく。弾性クエリフィルタチャレンジ

query = { 
    size: 0, 
    query: { 
    bool: { 
     filter: [ 
     { 
      constant_score: { 
      filter: { 
       terms: { 
       sku: { 
        index: "product_skus", 
        type: "product", 
        id: supplier_id, 
        path: "skus" 
       } 
       } 
      } 
      } 
     } 
     ], 
     must_not: [] 
    } 
    }, 
    aggs: { 
    unit_sum: { 
     terms: { 
     field: "sku", 
     size: 100, 
     order: { 
      one: "desc" 
     } 
     }, 
     aggs: { 
     one: { 
      sum: { 
      field: "units" 
      } 
     } 
     } 
    } 
    } 
} 

ここで、特定のユーザーがサプライヤーskusのサブセットに限定してアクセスする必要があるシナリオがあります。私はこれに取り組む最善の方法の周りに頭を抱えようとしています。ユーザーがSkusにアクセスして2回目の検索を行うことができる別のインデックスを持つことに傾いていますが、クエリロジックを頭に浮かべることはできません。例えば、簡単に言えば

。上記の問合せでサプライヤ1の場合は、製品[A、B、C、D、E] を返し、ユーザーJohnは製品[A、C、E]に基づく結果のみを表示します。 これを行うためのクエリ? boolの内側のフィルタの後にshould節を追加するのと同じくらい簡単ですか?

ありがとうございます!

+0

実際には、特定のユーザーがアクセス権を持っているSKUの数に依存します...少数の場合は、追加のSHOULD句を使用して逃げることができます。それが何百もの場合、別の解決策が必要になるでしょう。 –

+0

はい、数千ではないにしても数百になるのが好きです。 – Raoot

+0

ルーティングの使用について考えましたか? https://www.elastic.co/blog/customizing-your-document-routing – Adonis

答えて

0

シナリオではユーザーにルーティングを使用できるため、この状況ではおそらくルーティングが必要です。データを別々のシャードに編成することの追加のボーナスとして、ルーティングでクエリを使用するときのパフォーマンスを向上させることができます。どうして?ルーティングを使用すると、クラスタ内のすべてのノードではなく、関連するデータを含むシャードにのみ要求が送信されるためです。

何それはあなたのケースのように見えるのでしょうか?

product_skusのマッピング(必要に応じて変更します):のは単純なマッピング、およびIDのみ123でアクセスする必要がある製品に見てみましょう

PUT product_skus 
{ 
    "settings": { 
    "index": { 
     "number_of_shards": "5", 
     "number_of_replicas": "1" 
    } 

    }, 
    "mappings": { 
    "product": { 
     "_routing": { 
     "required": true 
     }, 
     "properties": { 
     "supplierId":{ 
      "type": "integer" 
     }, "path":{ 
      "type": "string" 
     } 
     } 
    } 
    } 
} 

は、今度は、製品を入れてみましょうインデックスタイプ(ルーティングを気づか):

POST product_skus/product?routing=123 
{ 
    "supplierId": 123, 
    "path": "some/path" 
} 

そして最後に、ルーティングを使用して2つの要求とその出力:

GET product_skus/_search?routing=123 
{ 
    "query": { 
    "match_all": {} 
    } 
} 

出力:

{ 
    "took": 4, 
    "timed_out": false, 
    "_shards": { 
    "total": 1, 
    "successful": 1, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 1, 
    "max_score": 1, 
    "hits": [ 
     { 
     "_index": "product_skus", 
     "_type": "product", 
     "_id": "AVrMHzgx28yun46LEMYm", 
     "_score": 1, 
     "_routing": "123", 
     "_source": { 
      "supplierId": 123, 
      "path": "some/path" 
     } 
     } 
    ] 
    } 
} 

2番目のクエリ:

GET product_skus/_search?routing=124 
{ 
    "query": { 
    "match_all": {} 
    } 
} 

出力:

{ 
    "took": 1, 
    "timed_out": false, 
    "_shards": { 
    "total": 1, 
    "successful": 1, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 0, 
    "max_score": null, 
    "hits": [] 
    } 
} 

それが唯一の簡単な例である、あなたはより多くの情報のためのマニュアルを確認する場合があります

つのみ断片をルーティングに使用される次の番組:

GET product_skus/_search_shards?routing=123 

出力:

{ 
    "nodes": { 
    "1sMKtN6aQ9yyOsTjknWyQA": { 
     "name": "1sMKtN6", 
     "ephemeral_id": "X-V2QGTwTmqUFQb1B6KIUw", 
     "transport_address": "127.0.0.1:9300", 
     "attributes": {} 
    } 
    }, 
    "shards": [ 
    [ 
     { 
     "state": "STARTED", 
     "primary": true, 
     "node": "1sMKtN6aQ9yyOsTjknWyQA", 
     "relocating_node": null, 
     "shard": 0, 
     "index": "product_skus", 
     "allocation_id": { 
      "id": "1MMkFaALRxm1N-x8J8AGhg" 
     } 
     } 
    ] 
    ] 
} 

がよりためsearch shards APIを見ます詳細。