ElasticSearch - 无法过滤字符串数组
ElasticSearch - Unable to filter on an array of strings
我有以下型号 class:
public class NewsItem
{
public String Language { get; set; }
public DateTime DateUpdated { get; set; }
public List<String> Tags { get; set; }
}
我使用自动映射在 NEST 中对其进行索引,生成如下映射:
{
"search": {
"mappings": {
"news": {
"properties": {
"dateUpdated": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"language": {
"type": "string"
},
"tags": {
"type": "string"
},
}
}
}
}
}
然后我 运行 查询了一个工作正常的语言:
{
"query": {
"constant_score": {
"filter": [
{
"terms": {
"language": [
"en"
]
}
}
]
}
},
"sort": {
"dateUpdated": {
"order": "desc"
}
}
}
但是 运行在标签 属性 上执行相同的查询不起作用。查询数组字段有什么特别的技巧吗?我一遍又一遍地阅读文档,但我不明白为什么这个查询没有结果:
{
"query": {
"constant_score": {
"filter": [
{
"terms": {
"tags": [
"Hillary"
]
}
}
]
}
},
"sort": {
"dateUpdated": {
"order": "desc"
}
}
}
从另一个查询返回的文档:
{
"_index": "search",
"_type": "news",
"_score": 0.12265198,
"_source": {
"tags": [
"Hillary"
],
"language": "en",
"dateUpdated": "2016-11-07T15:41:00Z"
}
}
您的 tags
字段已被分析,因此 Hillary
已被索引到 hillary
。所以你有两条出路:
一个。请改用 match
查询(因为 terms
查询不分析标记
{
"query": {
"bool": {
"filter": [
{
"match": { <--- use match here
"tags": "Hillary"
}
}
]
}
},
"sort": {
"dateUpdated": {
"order": "desc"
}
}
}
乙。保留 terms
查询但将标记小写:
{
"query": {
"bool": {
"filter": [
{
"terms": {
"tags": [
"hillary" <--- lowercase here
]
}
}
]
}
},
"sort": {
"dateUpdated": {
"order": "desc"
}
}
}
默认情况下,Elasticsearch 对所有字符串运行分析器,但在另一方面计算机精确匹配上运行 Terms 过滤器。因此,这意味着当您查询 'Hillary' 时,ES 将 'Hillary' 存储为 'hillary'。所以,有两种方法可以解决这个问题。您要么使用匹配查询而不是术语查询,要么您不自动映射而是创建索引并根据需要分析标签字段。您也可以查询 'hillary' 但这将是这种情况的解决方案,因为如果标签类似于 'us elections' 我们和选举都将单独存储。
我有以下型号 class:
public class NewsItem
{
public String Language { get; set; }
public DateTime DateUpdated { get; set; }
public List<String> Tags { get; set; }
}
我使用自动映射在 NEST 中对其进行索引,生成如下映射:
{
"search": {
"mappings": {
"news": {
"properties": {
"dateUpdated": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"language": {
"type": "string"
},
"tags": {
"type": "string"
},
}
}
}
}
}
然后我 运行 查询了一个工作正常的语言:
{
"query": {
"constant_score": {
"filter": [
{
"terms": {
"language": [
"en"
]
}
}
]
}
},
"sort": {
"dateUpdated": {
"order": "desc"
}
}
}
但是 运行在标签 属性 上执行相同的查询不起作用。查询数组字段有什么特别的技巧吗?我一遍又一遍地阅读文档,但我不明白为什么这个查询没有结果:
{
"query": {
"constant_score": {
"filter": [
{
"terms": {
"tags": [
"Hillary"
]
}
}
]
}
},
"sort": {
"dateUpdated": {
"order": "desc"
}
}
}
从另一个查询返回的文档:
{
"_index": "search",
"_type": "news",
"_score": 0.12265198,
"_source": {
"tags": [
"Hillary"
],
"language": "en",
"dateUpdated": "2016-11-07T15:41:00Z"
}
}
您的 tags
字段已被分析,因此 Hillary
已被索引到 hillary
。所以你有两条出路:
一个。请改用 match
查询(因为 terms
查询不分析标记
{
"query": {
"bool": {
"filter": [
{
"match": { <--- use match here
"tags": "Hillary"
}
}
]
}
},
"sort": {
"dateUpdated": {
"order": "desc"
}
}
}
乙。保留 terms
查询但将标记小写:
{
"query": {
"bool": {
"filter": [
{
"terms": {
"tags": [
"hillary" <--- lowercase here
]
}
}
]
}
},
"sort": {
"dateUpdated": {
"order": "desc"
}
}
}
默认情况下,Elasticsearch 对所有字符串运行分析器,但在另一方面计算机精确匹配上运行 Terms 过滤器。因此,这意味着当您查询 'Hillary' 时,ES 将 'Hillary' 存储为 'hillary'。所以,有两种方法可以解决这个问题。您要么使用匹配查询而不是术语查询,要么您不自动映射而是创建索引并根据需要分析标签字段。您也可以查询 'hillary' 但这将是这种情况的解决方案,因为如果标签类似于 'us elections' 我们和选举都将单独存储。