如何在 Elasticsearch 中搜索空值

科技公元 后端 Android 2024-06-11

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

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

选项 1:null_value 映射参数

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

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

复制代码
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 或空数组。bash

复制代码
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. }

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

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

上面的搜索结果为:json

复制代码
` 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. } `![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

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

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

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

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

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

选项2:使用 MUST_NOT 查询

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

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

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

复制代码
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. }

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

复制代码
` 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. } `![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

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

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

转载来源:https://juejin.cn/post/7192404587754553404

Apipost 私有化火热进行中

评论