脚本过滤器字段值在数组中

时间:2018-12-19 17:19:29

标签: elasticsearch elastic-stack

这是我查询的一部分:

 must_not: {
    script: {
      script: {
        source: "doc['type.keyword'].value=='CHANNEL' ? doc['id'].value == 0 : doc['id'].value.contains(['1','3','7'])",
        lang: 'painless'
      }
    }
  }

如何检查doc['id'].value是否具有数组中的值?

我尝试了不同的方法:

source:"doc['type.keyword'].value=='CHANNEL' ? doc['id'].value == 0 : params.ids.values.contains(doc['id'].value)",
 params: {
   ids: [5,6]
}

source:"doc['type.keyword'].value=='CHANNEL' ? doc['id'].value == 0 : params.ids.contains(doc['id'].value)",
 params: {
   ids: ['5','6']
}

source:"doc['type.keyword'].value=='CHANNEL' ? doc['id'].value == 0 : for (el in params.ids) {doc['id'].value==el}",
 params: {
   ids: ['5','6']
} . ERROR

唯一的工作方式是没有数组,但是对我没有帮助:

source:"doc['type.keyword'].value=='CHANNEL' ? doc['id'].value == 0 : doc['id'].value==params.ids",
 params: {
   ids: 5
}

完整的查询:

searchStr = 'a string' //dynamic
types = ['CHANNEL', 'AUDIO', 'ALBUM', 'MOVIE'] .  ///dynamic array of strings
searchAllTypes = ['CHANNEL', 'AUDIO', 'ALBUM', 'MOVIE']
excludedContent = [1, 5, 6, 8] - //a dynamic array
genres = 'aString' //dynamic
tag = 3 //dynamic
       query:
       {
         bool: {
           should:
           [
               //1.here is a function I use, but I added the entire code so it can be read better
               return types.map(type => {
             type === 'CHANNEL' ? excludedContentIds = [] : excludedContentIds = excludedContents; //2.this is my workaround -
   the line I want to get rid of
             return {
               bool: {
                 must: [
                   { match: { 'type': type } }, //3.if I get rid of line (2) I would use filter - terms - all types here. 
                   //But trying to use terms in combination with 'execution='OR'' is not working inside filters anymore, but inside
   query  
                   { match: { 'discoverable': true } },
                   { match: { 'status': 'PUBLISHED' } },
                   { match: { 'category.name': genres } },
                   { match: { 'tag.id': tag } },
                   {
                     multi_match: {
                       query: searchStr,
                       type: 'phrase_prefix',
                       slop: 5,
                       fields: config.elasticSearch.search.fields,
                       operator: 'AND',
                     }
                   }
                 ],
                 //// must_not workaround now, because I'm filtering excludedContentIds for CHANNEL in the function above (2)
                 must_not: [
                   { terms: { 'id': excludedContentIds } }
                 ]
               }
             };
           });
             ]
         }
       },
       aggs: {
         'by_top_first': {
           terms: {
             field: 'type.keyword',
               size: searchAllTypes.length,
             },
           aggs: {
             'by_top_hit': { top_hits: { size: 1 } },
             'max_score': { max: { script: '_score' } },
           }
         }
       },
       {
         'by_type': {
           terms: {
             field: 'type.keyword',
               size: searchAllTypes.length
           },
           aggs: {
             'by_top_hit': { top_hits: { size: limitSize ? limitSize : 6 } },
             'max_score': { max: { script: '_score' } },
           }
         }
       }

1 个答案:

答案 0 :(得分:0)

您可以简单地将数组值声明为脚本参数,然后在脚本中使用它来测试它是否包含值:

must_not: {
  script: {
    script: {
      source: "doc['type.keyword'].value=='CHANNEL' ? doc['id'].value == 0 : params.ids.contains(doc['id'].value)",
      params: {
        ids: ['1','3','7']
      },
      lang: 'painless'
    }
  }
}

有关更多信息,请参见Painless docs