percolator 字段将 Json 结构解析为一个本地查询,并将其存储,以便 percolator 查询可以用它来匹配提供的文档。
包含 json 对象的任何字段都可以配置为 percolator 字段。percolator 字段类型没有任何设置。仅仅配置 percolator字段类型就足以指示 elasticsearch 将字段视为查询。
如下映射将 query字段设置为 percolator类型:

  1. curl -X PUT "localhost:9200/my_index?pretty" -H 'Content-Type: application/json' -d'
  2. {
  3. "mappings": {
  4. "_doc": {
  5. "properties": {
  6. "query": {
  7. "type": "percolator"
  8. },
  9. "field": {
  10. "type": "text"
  11. }
  12. }
  13. }
  14. }
  15. }
  16. '

索引一个查询:

  1. curl -X PUT "localhost:9200/my_index/_doc/match_value?pretty" -H 'Content-Type: application/json' -d'
  2. {
  3. "query" : {
  4. "match" : {
  5. "field" : "value"
  6. }
  7. }
  8. }
  9. '

percolator 查询中引用的字段必须在用于 percolator 查询的索引映射中存在。为了确保这些字段存在,通过 create indexput mappingAPIs 创建及更新映射。过滤查询引用的字段可以存在于任何类型的,包含 percolator 字段类型的索引中。

重新索引 percolator 查询

重新索引 percolator 查询有时候是为了获取新的发新版中 percolator字段的改进。可以使用 reindex api来对 percolator 查询重建索引。让我们看一下带有 percolator 字段的索引:

  1. PUT index
  2. {
  3. "mappings": {
  4. "_doc" : {
  5. "properties": {
  6. "query" : {
  7. "type" : "percolator"
  8. },
  9. "body" : {
  10. "type": "text"
  11. }
  12. }
  13. }
  14. }
  15. }
  16. POST _aliases
  17. {
  18. "actions": [
  19. {
  20. "add": {
  21. "index": "index",
  22. "alias": "queries"
  23. }
  24. }
  25. ]
  26. }
  27. PUT queries/_doc/1?refresh
  28. {
  29. "query" : {
  30. "match" : {
  31. "body" : "quick brown fox"
  32. }
  33. }
  34. }

始终建议为索引定义别名,以便于一个重建索引的系统/应用不需要去知道 percolator 已经换了一个不同的索引。 假设你将要升级到一个新的版本,为了让新的版本依然能够读取到你的查询,需要将查询重新索引到目前的新版本 elasticsearch 中:

  1. PUT new_index
  2. {
  3. "mappings": {
  4. "_doc" : {
  5. "properties": {
  6. "query" : {
  7. "type" : "percolator"
  8. },
  9. "body" : {
  10. "type": "text"
  11. }
  12. }
  13. }
  14. }
  15. }
  16. POST /_reindex?refresh
  17. {
  18. "source": {
  19. "index": "index"
  20. },
  21. "dest": {
  22. "index": "new_index"
  23. }
  24. }
  25. POST _aliases
  26. {
  27. "actions": [
  28. {
  29. "remove": {
  30. "index" : "index",
  31. "alias": "queries"
  32. }
  33. },
  34. {
  35. "add": {
  36. "index": "new_index",
  37. "alias": "queries"
  38. }
  39. }
  40. ]
  41. }

如果有一个索引,不要忘记指向新的索引。 通过queries别名执行 percolate查询:

  1. GET /queries/_search
  2. {
  3. "query": {
  4. "percolate" : {
  5. "field" : "query",
  6. "document" : {
  7. "body" : "fox jumps over the lazy dog"
  8. }
  9. }
  10. }
  11. }

新索引返回匹配项:

  1. {
  2. "took": 3,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 5,
  6. "successful": 5,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": 1,
  12. "max_score": 0.2876821,
  13. "hits": [
  14. {
  15. "_index": "new_index",
  16. "_type": "_doc",
  17. "_id": "1",
  18. "_score": 0.2876821,
  19. "_source": {
  20. "query": {
  21. "match": {
  22. "body": "quick brown fox"
  23. }
  24. }
  25. },
  26. "fields": {
  27. "_percolator_document_slot": [
  28. 0
  29. ]
  30. }
  31. }
  32. ]
  33. }
  34. }

现在,从新索引中获取到了 percolator 命中的结果。

优化查询时间文本分析

当过滤器验证过滤候选匹配时,它将进行解析,执行查询时间文本分析,并且在要过滤文旦上实际运行过滤查询。这是针对每个候选匹配项,以及每次执行 percolator都要做的。对于查询解析,如果你的查询时间文本分析是相对比较昂贵的一部分,那么文本分析将会是过滤查询主要耗时的因素。当过滤器最终验证很多候选查询匹配时,该查询解析的开销会很明显。