【问题标题】:ngram for wildcard search in Elastic Search用于 Elastic Search 中的通配符搜索的 ngram
【发布时间】:2016-12-15 10:22:03
【问题描述】:

我正在尝试为最终用户提供搜索时使用的类型,这更像是 sqlserver。我能够为给定的 sql 场景实现 ES 查询:

 select * from table where name like '%peter tom%' and type != 'xyz 

在 ES 中,我使用 ngram tokenizer 来达到预期的效果:

PUT sample
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_ngram_analyzer": {
          "tokenizer": "my_ngram_tokenizer"
        }
      },
      "tokenizer": {
        "my_ngram_tokenizer": {
          "type": "nGram",
          "min_gram": "2",
          "max_gram": "15"
        }
      }
    }
  },
  "mappings": {
    "typename": {
      "properties": {
        "name": {
          "type": "string",
          "fields": {
            "search": {
              "type": "string",
              "analyzer": "my_ngram_analyzer"
            }
          }
        },
        "type": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }
  }
}

{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "name.search": "peter tom"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "type": "xyz"
          }
        },
        {
          "match": {
            "type": "abc"
          }
        }
      ]
    }
  }
}

所以如果我的文档行是这样的

name                              type
peter tomson                      efg
Peter tomson robert simson        efg

上面的查询只显示了两个文档,但是当我尝试输入 Peter sims 或 Peter simson 时,它不会返回第二个文档,除非我输入 Peter tomson robert sims 或 Peter tomson robert simson。所以基本上我必须输入Peter 之后和 simson 之前的所有以下单词都可以到达第二个文档。有什么方法可以让第二个文档进行部分匹配。我可以使用查询匹配和“AND”操作,但这仍然是单词的完全匹配。我正在寻找像 Peter sims 这样的部分匹配应该给我第二行的文件。 谢谢

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    我自己找到了查询的答案,并发布了解决方案以供其他用户进一步参考:

    {
        "settings": {
            "analysis": {
                "analyzer": {
                    "autocomplete": {
                        "tokenizer": "whitespace",
                        "filter": [
                            "lowercase",
                            "autocomplete"
                        ]
                    },
                    "autocomplete_search": {
                        "tokenizer": "whitespace",
                        "filter": [
                            "lowercase"
                        ]
                    }
                },
                "filter": {
                    "autocomplete": {
                        "type": "nGram",
                        "min_gram": 2,
                        "max_gram": 40
                    }
                }
            }
        },
        "mappings": {
            "doc": {
                "properties": {
                    "title": {
                        "type": "string",
                        "analyzer": "autocomplete",
                        "search_analyzer": "autocomplete_search"
                    }
                }
            }
        }
    }
    
    PUT my_index/doc/1
    {
      "title": "peter tomson" 
    }
    
    PUT my_index/doc/2
    {
      "title": "Peter tomson robert simson" 
    }
    
    
    GET my_index/doc/_search
        {
          "query": {
            "match": {
              "title": {
                "query": "Pete sim", 
                "operator": "and"
              }
            }
          }
        }
    

    【讨论】:

    • 感谢分享。帮助像我这样的初学者!
    • 我认为它在某些情况下会失败。尝试再插入 2 个文档(“SP SSPT”、“PSS SSPT2”)并搜索“sp sspt”,它给出了两个结果。
    猜你喜欢
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2021-01-14
    相关资源
    最近更新 更多