匹配查询中的所有精确单词

z4bn682m  于 2021-06-10  发布在  ElasticSearch
关注(0)|答案(2)|浏览(534)

我想使用elasticsearch javaapi创建一个查询,它只匹配(1)完整的单词和(2)searchquery中的所有单词。下面是一个例子:
文本: hello wonderful world 这些应匹配:

  1. hello
  2. hello wonderful
  3. hello world
  4. wonderful world
  5. hello wonderful world
  6. wonderful
  7. world

这些不应该匹配:
hell hello fniefsgbsugbs 我为匹配查询尝试了以下参数,但它仍然匹配上面的两个示例。
这是使用elasticsearch 7.7.1 java api生成查询的代码:

  1. import org.elasticsearch.index.query.QueryBuilders
  2. ...
  3. QueryBuilders.matchQuery(field, query)
  4. .autoGenerateSynonymsPhraseQuery(false)
  5. .fuzziness(0)
  6. .prefixLength(0)
  7. .fuzzyTranspositions(false)
  8. .operator(Operator.AND)
  9. .minimumShouldMatch("100%")

将生成此查询:

  1. {
  2. "size": 100,
  3. "query": {
  4. "bool": {
  5. "filter": [
  6. {
  7. "match": {
  8. "searchableText": {
  9. "query": "hell",
  10. "operator": "AND",
  11. "fuzziness": "0",
  12. "prefix_length": 0,
  13. "max_expansions": 50,
  14. "minimum_should_match": "100%",
  15. "fuzzy_transpositions": false,
  16. "lenient": false,
  17. "zero_terms_query": "NONE",
  18. "auto_generate_synonyms_phrase_query": false,
  19. "boost": 1
  20. }
  21. }
  22. }
  23. ]
  24. }
  25. }
  26. }

有人能帮我找到解决这个问题的好办法吗?
编辑:这里是设置和Map(我删除了所有与 searchableText 使其尽可能小):

  1. {
  2. "settings": {
  3. "analysis": {
  4. "normalizer": {
  5. "lowercase_normalizer": {
  6. "type": "custom",
  7. "filter": [
  8. "lowercase"
  9. ]
  10. }
  11. },
  12. "filter": {
  13. "german_stemmer": {
  14. "type": "stemmer",
  15. "language": "light_german"
  16. },
  17. "ngram_filter": {
  18. "type": "shingle",
  19. "max_shingle_size": 4,
  20. "min_shingle_size": 2,
  21. "output_unigrams": false,
  22. "output_unigrams_if_no_shingles": false
  23. }
  24. },
  25. "analyzer": {
  26. "german": {
  27. "tokenizer": "standard",
  28. "filter": [
  29. "lowercase",
  30. "german_synonyms",
  31. "german_stop",
  32. "german_keywords",
  33. "german_no_stemming",
  34. "german_stemmer"
  35. ]
  36. },
  37. "german_ngram": {
  38. "tokenizer": "standard",
  39. "filter": [
  40. "lowercase",
  41. "german_synonyms",
  42. "german_keywords",
  43. "german_no_stemming",
  44. "german_stemmer",
  45. "ngram_filter"
  46. ]
  47. }
  48. }
  49. }
  50. },
  51. "mappings": {
  52. "properties": {
  53. "description": {
  54. "type": "text",
  55. "copy_to": "searchableText",
  56. "analyzer": "german"
  57. },
  58. "name": {
  59. "type": "text",
  60. "copy_to": "searchableText",
  61. "analyzer": "german"
  62. },
  63. "userTags": {
  64. "type": "keyword",
  65. "copy_to": "searchableText",
  66. "normalizer": "lowercase_normalizer"
  67. },
  68. "searchableText": {
  69. "type": "text",
  70. "analyzer": "german",
  71. "fields": {
  72. "ngram": {
  73. "type": "text",
  74. "analyzer": "german_ngram"
  75. }
  76. }
  77. },
  78. "searches": {
  79. "type": "keyword",
  80. "copy_to": "searchableText",
  81. "normalizer": "lowercase_normalizer"
  82. }
  83. }
  84. }
  85. }

编辑2:这些是提到的过滤器:

  1. "filter": {
  2. "german_stop": {
  3. "type": "stop",
  4. "stopwords": "_german_"
  5. },
  6. "german_stemmer": {
  7. "type": "stemmer",
  8. "language": "light_german"
  9. },
  10. "ngram_filter": {
  11. "type": "shingle",
  12. "max_shingle_size": 4,
  13. "min_shingle_size": 2,
  14. "output_unigrams": false,
  15. "output_unigrams_if_no_shingles": false
  16. }
  17. }
ipakzgxi

ipakzgxi1#

我尝试用你的设置和Map创建索引,但由于没有提供以下筛选器,我得到了错误,并在删除这些筛选器后创建了索引。

  1. "german_synonyms",
  2. "german_stop",
  3. "german_keywords",
  4. "german_no_stemming",

在那之后,我索引了你的样本文件 hello wonderful world 并使用了您的搜索查询,但它工作正常,如您预期的,没有返回结果 hell 或者 hello fniefsgbsugbs 如下图所示

  1. {
  2. "size": 100,
  3. "query": {
  4. "bool": {
  5. "filter": [
  6. {
  7. "match": {
  8. "searchableText": {
  9. "query": "hello fniefsgbsugbs",
  10. "operator": "AND",
  11. "fuzziness": "0",
  12. "prefix_length": 0,
  13. "max_expansions": 50,
  14. "minimum_should_match": "100%",
  15. "fuzzy_transpositions": false,
  16. "lenient": false,
  17. "zero_terms_query": "NONE",
  18. "auto_generate_synonyms_phrase_query": false,
  19. "boost": 1
  20. }
  21. }
  22. }
  23. ]
  24. }
  25. }
  26. }

它又回来了

  1. "hits": {
  2. "total": {
  3. "value": 0,
  4. "relation": "eq"
  5. },
  6. "max_score": null,
  7. "hits": []
  8. }

我也一样 hell ,而返回结果 hello , hello wonderful 以及其他预期匹配的条款。
编辑:您使用的是分析的匹配查询,即,它分析搜索项,应用与字段上应用索引时间相同的分析器,并将搜索时间标记与索引时间标记相匹配。
为了正确调试这类问题,请使用analyze api并检查索引文档标记和搜索词标记。

展开查看全部
jchrr9hc

jchrr9hc2#

对于索引为“关键字”的字段,我通常更喜欢querystring query dsl而不是match query。例如:

  1. {
  2. "query" : {
  3. "query_string" : {
  4. "query" : "my_field:('hello', 'wonderful', 'world')"
  5. }
  6. }
  7. }

将匹配所有您编写的应该匹配的组合,而不是您不想要的组合。括号中术语的关系类似于sql“in”,因此字段中出现的任何一个都将与文档匹配。另外,这种格式在创建复杂搜索时提供了极大的灵活性。如果这有帮助,请告诉我。

相关问题