2016-08-11 90 views
1

我有一个类型的弹性与文档这种结构排序嵌套场

{ 
    "name": "Foo Bar", 
    "myTags": [ 
    { 
     "id": 3, 
     "name": "My tag 1" 
    }, 
    { 
     "id": 5, 
     "name": "My Tag 5" 
    }, 
    { 
     "id": 7, 
     "name": "My Tag 7" 
    } 
    ] 
} 

现在,给3个标签,我想获得通过匹配标签的数量排序的所有文件。所以首先匹配所有3个标签的文档比那些匹配2个然后1个最终没有匹配的文档。

我该怎么做?

+0

您使用得分,这和使用'bool'三(3标签)'should'语句会加重计分,如果一个标签“匹配”(无论你的用例如何)。这个想法是,如果一个标签匹配,它会增加分数。 –

回答

0

你可以用function_score做到这一点:

{ 
    "query": { 
    "function_score": { 
     "query": { 
     "match_all": {} 
     }, 
     "functions": [ 
     { 
      "filter": { 
      "nested": { 
       "path": "myTags", 
       "query": { 
       "term": { 
        "myTags.name": "My Tag 1" 
       } 
       } 
      } 
      }, 
      "weight": 1 
     }, 
     { 
      "filter": { 
      "nested": { 
       "path": "myTags", 
       "query": { 
       "term": { 
        "myTags.name": "My Tag 5" 
       } 
       } 
      } 
      }, 
      "weight": 1 
     }, 
     { 
      "filter": { 
      "nested": { 
       "path": "myTags", 
       "query": { 
       "term": { 
        "myTags.name": "My Tag 7" 
       } 
       } 
      } 
      }, 
      "weight": 1 
     } 
     ], 
     "boost_mode": "sum", 
     "score_mode": "sum" 
    } 
    } 
} 
+0

我忘了提及我在Elastic 1.7.5上。这个查询是否正常? – Hpatoio

+0

它应该与1.7一起工作。这个想法是,如果一个文档匹配其中一个标签,分数就会得到+1。如果它与另一个标签匹配,那么另一个+1等等。基本上,最终得分将是匹配标签+1的数量(来自默认'match_all'默认查询)。 –

+0

我不得不将'weight:1'更改为'weight:2',否则当使用一个标签进行过滤时,我得到了奇怪/错误的结果。 – Hpatoio