ElasticSearch - 无法过滤字符串数组

时间:2016-11-09 09:46:22

标签: elasticsearch nest

我有以下模型类:

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"
    }
  }
}

但是在tags属性上运行相同的查询不起作用。查询数组字段有什么特殊技巧吗?我一次又一次地阅读文档,我不明白为什么这个查询没有结果:

{
  "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"
  }
}

2 个答案:

答案 0 :(得分:2)

分析了您的tags字段,因此Hillary已编入索引hillary。所以你有两种方法:

一个。请改为使用match查询(因为terms查询不会分析令牌

{
  "query": {
    "bool": {
      "filter": [
        {
          "match": {              <--- use match here
            "tags": "Hillary"
          }
        }
      ]
    }
  },
  "sort": {
    "dateUpdated": {
      "order": "desc"
    }
  }
}

B中。保留terms查询但小写令牌:

{
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {
            "tags": [
              "hillary"           <--- lowercase here
            ]
          }
        }
      ]
    }
  },
  "sort": {
    "dateUpdated": {
      "order": "desc"
    }
  }
}

答案 1 :(得分:1)

默认情况下,Elasticsearch会在所有字符串上运行分析器,但条款筛选器在其他计算机上完全匹配。所以这意味着ES正在存储希拉里&#39;作为希拉里&#39;当你在查询希拉里时#39;所以,有两种方法可以解决这个问题。您可以使用匹配查询而不是术语查询,也可以不自动创建索引并根据需要分析标记字段。您还可以查询希拉里&#39;但这对于这一个案例来说是一个解决方案,因为如果标签是类似于我们的选举&#39;我们和选举都将分开存储。