弹性搜索 - 获取不同的标签

时间:2015-02-03 16:20:14

标签: elasticsearch

我有以下格式的文件:

{
 _id :"1",
  tags:["guava","apple","mango", "banana", "gulmohar"]
}


{
  _id:"2",
  tags: ["orange","guava", "mango shakes", "apple pie", "grammar"]
}

{

  _id:"3",
  tags: ["apple","grapes", "water", "gulmohar","water-melon", "green"]
}

现在,我想从整个文档'标记字段中获取唯一标记值'从前缀g*开始,以便标记建议者显示这些唯一标记(Stackoverflow网站就是一个例子)。

例如:每当用户输入时,' g': 结果应该返回"guava", "gulmohar", "grammar", "grapes" and "green"。 即。查询应返回前缀为g *。

的不同标记

我到处尝试,浏览整个文档,搜索es论坛,但我没有找到任何线索,令我感到沮丧。

我尝试了聚合,但聚合会返回标记字段中整个单词/标记的不同计数。它不会返回以' g'。

开头的唯一标记列表
"query": {
    "filtered": {
      "query": {
        "bool": {
          "should": [
            {
              "query_string": {
                "allow_leading_wildcard": false,
                "fields": [
                  "tags"
                ],
                "query": "g*",
                "fuzziness":0
              }
            }
          ]
        }
      },
      "filter": {
         //some condition on other  field...
      }

    }

  },
  "aggs": {
    "distinct_tags": {
      "terms": {
        "field": "tags",
        "size": 10
      }
    }
  }, 

上述结果:番石榴(w),苹果(q),芒果(1),......

有人可以建议我使用前缀input_prefix *获取所有不同标签的正确方法吗?

2 个答案:

答案 0 :(得分:1)

这有点像黑客,但这似乎可以达到你想要的效果。

我创建了一个索引并添加了您的文档:

DELETE /test_index

PUT /test_index
{
   "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 0
   }
}

POST /test_index/_bulk
{"index":{"_index":"test_index","_type":"doc","_id":1}}
{"tags":["guava","apple","mango", "banana", "gulmohar"]}
{"index":{"_index":"test_index","_type":"doc","_id":2}}
{"tags": ["orange","guava", "mango shakes", "apple pie", "grammar"]}
{"index":{"_index":"test_index","_type":"doc","_id":3}}
{"tags": ["guava","apple","grapes", "water", "grammar","gulmohar","water-melon", "green"]}

然后我使用了prefix queryhighlighting的组合,如下所示:

POST /test_index/_search
{
   "query": {
      "prefix": {
         "tags": {
            "value": "g"
         }
      }
   },
   "fields": [ ], 
   "highlight": {
       "pre_tags": [""],
       "post_tags": [""], 
       "fields": {
           "tags": {}
       }
   }
}
...
{
   "took": 5,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 3,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1",
            "_score": 1,
            "highlight": {
               "tags": [
                  "guava",
                  "gulmohar"
               ]
            }
         },
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "2",
            "_score": 1,
            "highlight": {
               "tags": [
                  "guava",
                  "grammar"
               ]
            }
         },
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "3",
            "_score": 1,
            "highlight": {
               "tags": [
                  "guava",
                  "grapes",
                  "grammar",
                  "gulmohar",
                  "green"
               ]
            }
         }
      ]
   }
}

以下是我使用的代码: http://sense.qbox.io/gist/c14675ee8bd3934389a6cb0c85ff57621a17bf11

当然,你要做的事情相当于自动完成,并且有可能比我上面发布的更好的方式(尽管它们更多涉及)。以下是我们关于设置自动填充功能的几篇博文:

http://blog.qbox.io/quick-and-dirty-autocomplete-with-elasticsearch-completion-suggest

http://blog.qbox.io/multi-field-partial-word-autocomplete-in-elasticsearch-using-ngrams

答案 1 :(得分:1)

根据@Sloan Ahrens的建议,我做了以下事情:

更新了映射:

  "tags": {
      "type": "completion",
      "context": {
        "filter_color": {
          "type": "category",
          "default": "",
          "path": "fruits.color"
        },
        "filter_type": {
          "type": "category",
          "default": "",
          "path": "fruits.type"
        }
      }
   }

参考:ES API Guide

插入这些索引:

{
 _id :"1",
  tags:{input" :["guava","apple","mango", "banana", "gulmohar"]},
  fruits:{color:'bar',type:'alice'}
}


{
  _id:"2",
   tags:{["orange","guava", "mango shakes", "apple pie", "grammar"]}
   fruits:{color:'foo',type:'bob'}
}

{

  _id:"3",
  tags:{ ["apple","grapes", "water", "gulmohar","water-melon", "green"]}
  fruits:{color:'foo',type:'alice'}
}

我不需要修改很多,我的原始索引。刚刚在标记数组之前添加了input

POST rescu1/_suggest?pretty'
{
  "suggest": {
    "text": "g",
    "completion": {
      "field": "tags",
      "size": 10,
      "context": {
        "filter_color": "bar",
        "filter_type": "alice"
      }
    }
  }
}

给了我想要的输出。

我接受了@Sloan Ahrens的回答,因为他的建议对我来说就像一个魅力,他向我展示了正确的方向。