飞道的博客

Elasticsearch:如何在 Elasticsearch 中搜索空值

421人阅读  评论(0)

根据 Elasticsearch 文档,无法索引或搜索空值 null。 当一个字段设置为 null(或空数组或空值数组)时,它被视为该字段没有值。

那么如何找到 product_name 为空(null)的文件呢?

选项 1:null_value 映射参数

你可以在配置索引映射时定义 null_value 参数。 它将允许你在索引文档时用指定值替换显式空值 null,以便它可以被索引和搜索。

让我们创建索引名称 products,其中包含值为 NULL 的 product_name 字段。


  
  1. PUT products
  2. {
  3. "mappings": {
  4. "properties": {
  5. "product_name":{
  6. "type": "keyword",
  7. "null_value": "NULL"
  8. }
  9. }
  10. }
  11. }

让我们用 product_name 字段索引一些文档,该字段的值为 null 或空数组。


  
  1. POST products /_doc/ 1
  2. {
  3. "product_name": null,
  4. "company": "apple"
  5. }
  6. POST products /_doc/ 2
  7. {
  8. "product_name": [],
  9. "company": "apple"
  10. }

让我们查询并检查我们得到的结果:


  
  1. POST products/_search
  2. {
  3. "query": {
  4. "match": {
  5. "product_name": "NULL"
  6. }
  7. }
  8. }

上面的搜索结果为:


  
  1. {
  2. "took": 1009,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 0.2876821,
  16. "hits": [
  17. {
  18. "_index": "products",
  19. "_id": "1",
  20. "_score": 0.2876821,
  21. "_source": {
  22. "product_name": null,
  23. "company": "apple"
  24. }
  25. }
  26. ]
  27. }
  28. }

什么??? 为什么 Elasticsearch 只返回一个文档而不返回第二个具有空数组的文档? 因为,

  • 一个空数组不包含明确的 null,因此不会被 null_value 替换。

此外,product_name 值仅作为 null 而不是作为在索引映射中设置的 NULL。 因为,

  • null_value 只影响数据的索引方式,它不会修改 _source 文档。

现在,当 product_name 为 null 或空数组时,如何将两个文档都放入结果中?

选项2:使用 MUST_NOT 查询

让我们定义没有 null_value 的索引映射和与上面相同的索引文档。


  
  1. PUT products
  2. {
  3. "mappings": {
  4. "properties": {
  5. "product_name":{
  6. "type": "keyword"
  7. }
  8. }
  9. }
  10. }

现在你可以使用以下查询:


  
  1. POST products/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must_not": [
  6. {
  7. "exists": {
  8. "field": "product_name"
  9. }
  10. }
  11. ]
  12. }
  13. }
  14. }

上述查询的结果,它现在返回两个结果:


  
  1. {
  2. "took": 1,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 2,
  13. "relation": "eq"
  14. },
  15. "max_score": 0,
  16. "hits": [
  17. {
  18. "_index": "products",
  19. "_id": "1",
  20. "_score": 0,
  21. "_source": {
  22. "product_name": null,
  23. "company": "apple"
  24. }
  25. },
  26. {
  27. "_index": "products",
  28. "_id": "2",
  29. "_score": 0,
  30. "_source": {
  31. "product_name": [],
  32. "company": "apple"
  33. }
  34. }
  35. ]
  36. }
  37. }

将 must_not 与 exists 查询一起使用的优点:

  • 此选项 2 不依赖于字段的数据类型,无论字段的数据类型如何,它都会起作用,但选项 1 null_value 需要与字段的数据类型相同。 例如,长字段不能有字符串 null_value。
  • 选项 1 不适用于文本类型的字段,因为 Elasticsearch 不允许为文本类型的字段设置 null_value 参数。
  • 选项 2 也是单一且高效的解决方案,因为 1) 它不需要根据字段映射中定义的值添加 null 值的开销。2)索引大小也会变小,导致索引变少,搜索查询变快。

转载:https://blog.csdn.net/UbuntuTouch/article/details/128759296
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场