在匹配字段和数组长度的基础上搜索文档 - Elasticseach

时间:2015-09-16 05:01:13

标签: elasticsearch

我有一个类似于elasticsearch的文档结构,

putchar()

我想搜索包含{ _id: 1, name: 'abc', post: [{ type: 'text', url: '__url___' }, { type: 'image', url: '__url___' }, { type: 'text', url: '__url___' }, { type: 'video', url: '__url___' }, { type: 'text', url: '__url___' }] } type的帖子的文档,其中text出现次数超过两次。是否有可能在Elasticsearch?

1 个答案:

答案 0 :(得分:2)

选项1

您需要使用script进行此类搜索,对于名为post的字段和名为type的子字段:

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "script": {
          "script": "_source.post.type.count(param1)>2",
          "params": {
            "param1": "text"
          }
        }
      }
    }
  }
}

并确保您在配置文件中enable inline scripts

script.engine.groovy.inline.search: on

选项2

此操作也可以在索引时完成,以便在使用transform进行搜索时节省一些时间。像这样:

{
  "mappings": {
    "test": {
      "transform": {
        "script": "if(ctx._source.post.type.count(param1)>2) ctx._source['count_texts']=ctx._source.post.type.count(param1);",
        "params": {
            "param1": "text"
          }
      }, 
      "properties": {
        "name": {
          "type": "string"
        },
        "count_texts": {
          "type": "integer"
        },
...

确保在配置文件中启用正确的脚本设置:

script.engine.groovy.inline.mapping: on

而且,在搜索时,像这样的查询应该这样做:

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "range": {
          "count_texts": {
            "gte": 2
          }
        }
      }
    }
  }
}

transform的优点是重型脚本操作是在索引时执行的,而不是在搜索时执行的,并且搜索速度可能比在搜索时使用脚本时更快。

transform的缺点是,除非您在映射中定义另一个param1,否则无法为transform实际指定其他值。意思是,如果你想计算video,该怎么办?您需要添加另一个transform和另一个字段count_videos,例如。