【问题标题】:Create keyword string type with custom analyzer in 5.3.0在 5.3.0 中使用自定义分析器创建关键字字符串类型
【发布时间】:2017-04-17 23:00:12
【问题描述】:

我有一个字符串我想索引为关键字类型,但使用特殊的逗号分析器: 例如:

“旧金山,波士顿,纽约”->“旧金山”,“波士顿,“纽约”

应该同时被索引和聚合,以便我可以按桶将其拆分。在 5.0.0 之前,以下工作: 索引设置:

{
     'settings': {
         'analysis': {
             'tokenizer': {
                 'comma': {
                     'type': 'pattern',
                     'pattern': ','
                 }
             },
             'analyzer': {
                'comma': {
                     'type': 'custom',
                     'tokenizer': 'comma'
                 }
             }
         },
     },
}

具有以下映射:

{
    'city': {
        'type': 'string',
        'analyzer': 'comma'
    },
}

现在在5.3.0 及以上,分析器不再是关键字类型的有效属性,我的理解是我在这里想要一个keyword 类型。如何使用自定义分析器指定可聚合、索引、可搜索的文本类型?

【问题讨论】:

  • 在 5.2 及更高版本中,keyword 字段现在可以有 normalizers,但那些只允许特定的标记过滤器和字符过滤器,但没有标记器,所以这不是一种方法。在将它发送到 ES 之前,你有什么方法可以在客户端拆分该字符串?

标签: elasticsearch elasticsearch-5


【解决方案1】:

您可以使用multifields 以两种不同的方式索引相同的字段,一种用于搜索,另一种用于聚合。

我还建议您为trim 添加一个过滤器并将生成的标记小写以帮助您更好地搜索。

映射

PUT commaindex2
    {
        "settings": {
            "analysis": {
                "tokenizer": {
                    "comma": {
                        "type": "pattern",
                        "pattern": ","
                    }
                },
                "analyzer": {
                    "comma": {
                        "type": "custom",
                        "tokenizer": "comma",
                        "filter": ["lowercase", "trim"]
                    }
                }
            }
        },
        "mappings": {
            "city_document": {
                "properties": {
                    "city": {
                        "type": "keyword",
                        "fields": {
                            "city_custom_analyzed": {
                                "type": "text",
                                "analyzer": "comma",
                                "fielddata": true
                            }
                        }
                    }
                }
            }
        }
    }

索引文件

POST commaindex2/city_document
{
  "city" : "san fransisco, new york, london"
}

搜索查询

POST commaindex2/city_document/_search
{
    "query": {
        "bool": {
            "must": [{
                "term": {
                    "city.city_custom_analyzed": {
                        "value": "new york"
                    }
                }
            }]
        }
    },
    "aggs": {
        "terms_agg": {
            "terms": {
                "field": "city",
                "size": 10
            }
        }
    }
}

注意

如果您想在索引字段上运行 aggs,例如您想计算存储桶中的每个城市,您可以在 city.city_custom_analyzed 字段上运行术语聚合。

POST commaindex2/city_document/_search
{
    "query": {
        "bool": {
            "must": [{
                "term": {
                    "city.city_custom_analyzed": {
                        "value": "new york"
                    }
                }
            }]
        }
    },
    "aggs": {
        "terms_agg": {
            "terms": {
                "field": "city.city_custom_analyzed",
                "size": 10
            }
        }
    }
}

希望对你有帮助

【讨论】:

  • city 字段上运行术语聚合时会发生什么?您可能不会分别获得每个城市,对吧?
  • 是的,那么他可以改为在 city.city_custom_analyzed 字段上运行。他没有明确提到他想在哪里运行聚合。如果是这样,那么为什么他需要关键字,他可以应用自定义分析器并避免多字段。这取决于他,他可以选择任何领域。我会更新帖子。谢谢
【解决方案2】:

由于您使用的是 ES 5.3,我建议采用不同的方法,使用摄取管道在索引时拆分您的字段。

PUT _ingest/pipeline/city-splitter
{
  "description": "City splitter",
  "processors": [
    {
      "split": {
        "field": "city",
        "separator": ","
      }
    },
    {
      "foreach": {
        "field": "city",
        "processor": {
          "trim": {
            "field": "_ingest._value"
          }
        }
      }
    }
  ]
}

然后你可以索引一个新文档:

PUT cities/city/1?pipeline=city-splitter
{ "city" : "San Francisco, Boston, New York" }

最后,您可以在 city 上搜索/排序并在字段 city.keyword 上运行聚合,就像在您的客户端应用程序中拆分城市一样:

POST cities/_search
{
  "query": {
     "match": {
         "city": "boston"
     }
  },
  "aggs": {
    "cities": {
      "terms": {
        "field": "city.keyword"
      }
    }
  }
}

【讨论】:

  • 这个运气好吗?
猜你喜欢
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
相关资源
最近更新 更多