2017-05-24 21 views
2

完全な初心者は、ここでは不可能である可能性があります。 は私がElasticsearchに格納したい以下の構造を有する:ネストされたフィールド内で一致する数のElasticSearch順序

{ 
    "id" : 1, 
    "code" : "03f3301c-4089-11e7-a919-92ebcb67fe33", 
    "countries" : [ 
     { 
      "id" : 1, 
      "name" : "Netherlands" 
     }, 
     { 
      "id" : 2, 
      "name" : "United Kingdom" 
     } 
    ], 
    "tags" : [ 
     { 
      "id" : 1, 
      "name" : "Scanned" 
     }, 
     { 
      "id" : 2, 
      "name" : "Secured" 
     }, 
     { 
      "id" : 3, 
      "name" : "Cleared" 
     } 
    ] 
} 

私はそれが保存されるので、構造が変化することができますが、それは何らかの形でこれらすべてのフィールドを含める必要があります方法を完全に制御を持っています。 このデータにcountriestagsを照会して、少なくとも1つの一致があるすべてのアイテムが返され、一致の数で並べ替えられるようにしたいと考えています。可能であれば、私は全文検索をしたくないと思っています。例えば

:質問について

id, code, country ids, tag ids 
1, ..., [1, 2, 3], [1] 
2, ..., [1],   [1, 2, 3] 

"which of these was in country 1 or has tag 1 or has tag 2"、返すべき:

2, ..., [1], [1, 2, 3] 
1, ..., [1, 2, 3], [1] 

このために、第二行は上記和に複数のサブクエリに一致するからです。本質的には

、私はこのSQLクエリーを複製したいと思います:

SELECT p.id, p.code, COUNT(p.id) FROM packages p 
LEFT JOIN tags t ON t.package_id = p.id 
LEFT JOIN countries c ON c.package_id = p.id 
WHERE t.id IN (1, 2, 3) OR c.id IN (1, 2, 3) 
GROUP BY p.id 
ORDER BY COUNT(p.id); 

ことが重要ならば、私はElasticSearch 2.4.5を使用しています。

うまくいけば、私は十分に分かりました。ご協力ありがとうございました!

答えて

0

countriestagsnestedである必要があります。また、function_scoreのスコアリングをコントロールする必要があります。weight1で、function_score内のクエリではboost_modescore_modeで再生されます。このクエリを使用することができ、最終的に:

GET /nested/test/_search 
{ 
    "query": { 
    "function_score": { 
     "query": { 
     "match_all": {} 
     }, 
     "functions": [ 
     { 
      "filter": { 
      "nested": { 
       "path": "tags", 
       "query": { 
       "term": { 
        "tags.id": 1 
       } 
       } 
      } 
      }, 
      "weight": 1 
     }, 
     { 
      "filter": { 
      "nested": { 
       "path": "tags", 
       "query": { 
       "term": { 
        "tags.id": 2 
       } 
       } 
      } 
      }, 
      "weight": 1 
     }, 
     { 
      "filter": { 
      "nested": { 
       "path": "countries", 
       "query": { 
       "term": { 
        "countries.id": 1 
       } 
       } 
      } 
      }, 
      "weight": 1 
     } 
     ], 
     "boost_mode": "replace", 
     "score_mode": "sum" 
    } 
    } 
} 

より完全なテストケースのために、私はまた、マッピングおよびテストデータを提供しています:

PUT nested 
{ 
    "mappings": { 
    "test": { 
     "properties": { 
     "tags": { 
      "type": "nested", 
      "properties": { 
      "name": { 
       "type": "string", 
       "index": "not_analyzed" 
      } 
      } 
     }, 
     "countries": { 
      "type": "nested", 
      "properties": { 
      "name": { 
       "type": "string", 
       "index": "not_analyzed" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

POST nested/test/_bulk 
{"index":{"_id":1}} 
{"name":"Foo Bar","tags":[{"id":2,"name":"My Tag 5"},{"id":3,"name":"My Tag 7"}],"countries":[{"id":1,"name":"USA"}]} 
{"index":{"_id":2}} 
{"name":"Foo Bar","tags":[{"id":3,"name":"My Tag 6"}],"countries":[{"id":1,"name":"USA"},{"id":2,"name":"UK"},{"id":3,"name":"UAE"}]} 
{"index":{"_id":3}} 
{"name":"Foo Bar","tags":[{"id":1,"name":"My Tag 4"},{"id":3,"name":"My Tag 1"}],"countries":[{"id":3,"name":"UAE"}]} 
{"index":{"_id":4}} 
{"name":"Foo Bar","tags":[{"id":1,"name":"My Tag 1"},{"id":2,"name":"My Tag 4"},{"id":3,"name":"My Tag 2"}],"countries":[{"id":2,"name":"UK"},{"id":3,"name":"UAE"}]} 
+0

は完全に働いたこと、ありがとうございます!私がしなければならなかった小さな変化は、すべての関数の '重み'を2に設定し、2の 'min_score'を追加しました。なぜなら、文書がいずれのフィルタとも一致しないと、スコア '1' 。 – Robert

関連する問題