Elasticsearch:存储没有重复的标签

时间:2017-07-28 10:01:16

标签: elasticsearch groovy duplicates set

我想以一种我不会重复的方式在我的文档中存储标记。

我的文档的Tags字段定义为:

...
"Tags": { "type": "string" }
...

我将标签添加到Python的Tags字段中:

es.update(index=ES_INDEX, doc_type=ES_DOC_TYPE, id=user_id, body=doc)

我的更新文档:

doc = {
  "script": {
    "lang": "groovy",
    "inline": "ctx._source.Tags.addAll(tags)",
    "params": {
      "tags": [
        "c#",
        "winforms",
        "type-conversion",
        "decimal",
        "opacity"
      ]
    }
  }
}

这样可行,但标签可能会重复。

我希望在存储标签之前对其进行重复数据删除。我基本上希望Tags字段作为一个集合。

这是我尝试的内容(基于这个答案:https://stackoverflow.com/a/17465831/318557

...
"inline": "ctx._source.Tags.addAll(tags); ctx._source.Tags.unique();",
...

但它没有效果。

是否有Groovy解决方案可以做到这一点?或者也许Elasticsearch支持存储集?

2 个答案:

答案 0 :(得分:1)

我不认为这是一个时髦的问题。你在检查正确的物体吗?

我已将以下文档编入索引:

{
    "_index": "script",
    "_type": "test",
    "_id": "AV2Jd1zXM1eNU8lqyoZS",
    "_score": 1,
    "_source": {
        "Tags": [
            "tag1",
            "decimal"
        ]
    }
}

并致电:

curl -X POST \
  http://127.0.0.1:9200/script/test/AV2Jd1zXM1eNU8lqyoZS/_update \
  -d '{
  "script": {
    "lang": "groovy",
    "inline": "ctx._source.Tags.addAll(tags); ctx._source.Tags.unique();",
    "params": {
      "tags": [
        "c#",
        "winforms",
        "type-conversion",
        "decimal",
        "opacity",
        "aaa",
        "aaa"
      ]
    }
  }
}'

结果:

{
    "_index": "script",
    "_type": "test",
    "_id": "AV2Jd1zXM1eNU8lqyoZS",
    "_score": 1,
    "_source": {
        "Tags": [
            "tag1",
            "decimal",
            "c#",
            "winforms",
            "type-conversion",
            "opacity",
            "aaa"
        ]
}

所以groovy在这里运行正常,请自行查看一些REST客户端。您可以尝试重新分配集合:

"inline": "ctx._source.Tags = ctx._source.Tags.unique(); ctx._source.Tags += tags.unique();",

也许这是Python代码的问题?

答案 1 :(得分:0)

问题是在初始化数组上使用.addAll()。使用REST客户端给了我这样的信息:

{
  "error": {
    "root_cause": [
      {
        "type": "remote_transport_exception",
        "reason": "[DevHunt][192.168.1.98:9300][indices:data/write/update[s]]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "failed to execute script",
    "caused_by": {
      "type": "script_exception",
      "reason": "error evaluating ctx._source.Tags.addAll(tags);",
      "script_stack": [],
      "script": "",
      "lang": "groovy",
      "caused_by": {
        "type": "null_pointer_exception",
        "reason": "Cannot invoke method addAll() on null object"
      }
    }
  },
  "status": 400
}

解决方案是使用:

...
"inline": "if(ctx._source.Tags == null) {ctx._source.Tags = [];}; ctx._source.Tags.addAll(tags); ctx._source.Tags.unique();",
...