【问题标题】:Elastic Search not giving exact results python弹性搜索没有给出确切的结果python
【发布时间】:2019-03-02 10:07:02
【问题描述】:

我正在使用匹配短语查询在 ES 中查找。但我注意到返回的结果不合适。 代码——

      res = es.search(index=('indice_1'),

               body = {
    "_source":["content"],

    "query": {
        "match_phrase":{
        "content":"xyz abc"
        }}}

   ,
size=500,
scroll='60s')

它没有让我记录内容在哪里 - “嗨,我的名字是 xyz abc。”和“嘿 wassupxyz abc。生活怎么样”

在 mongodb 中使用 regex 进行类似的搜索也会得到这两个记录。任何帮助将不胜感激。

【问题讨论】:

  • 你用的是什么分析仪?
  • 我是 ES 新手。我没有使用任何。
  • 我应该使用任何特定的分析仪吗?

标签: python python-3.x mongodb elasticsearch elastic-stack


【解决方案1】:

如果您没有指定分析器,则默认使用standard。它将进行基于语法的标记化。因此,您对“嗨,我的名字 isxyz abc”这句话的用语。将类似于 [hi, my, name, isxyz, abc]match_phrase 正在寻找彼此相邻的术语 [xyz, abc](除非您指定 slop)。

您可以使用不同的分析器或修改您的查询。如果您使用match 查询,它将匹配术语“abc”。如果您希望短语匹配,则需要使用不同的分析器。 NGrams 应该适合你。

这是一个例子:

PUT test_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 3,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  }, 
  "mappings": {
    "_doc": {
      "properties": {
        "content": {
          "type": "text",
          "analyzer": "my_analyzer"
        }
      }
    }
  }
}

PUT test_index/_doc/1
{
  "content": "hi my name isxyz abc."
}

PUT test_index/_doc/2
{
  "content": "hey wassupxyz abc. how is life"
}

POST test_index/_doc/_search
{
  "query": {
    "match_phrase": {
      "content": "xyz abc"
    }
  }
}

这会导致找到两个文档。

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.5753642,
    "hits": [
      {
        "_index": "test_index",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.5753642,
        "_source": {
          "content": "hey wassupxyz abc. how is life"
        }
      },
      {
        "_index": "test_index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.5753642,
        "_source": {
          "content": "hi my name isxyz abc."
        }
      }
    ]
  }
}

编辑: 如果您要进行wildcard 查询,可以使用standard 分析器。您在 cmets 中指定的用例将像这样添加:

PUT test_index/_doc/3
{
  "content": "RegionLasit Pant0Q00B000001KBQ1SAO00"
}

你可以用wildcard查询:

POST test_index/_doc/_search
{
  "query": {
    "wildcard": {
      "content.keyword": {
        "value": "*Lasit Pant*"
      }
    }
  }
}

基本上你是在没有nGram 分析器的情况下进行子字符串搜索。然后,您的查询短语将只是 "*<my search terms>*"。我仍然建议您查看nGrams

【讨论】:

  • 我刚刚阅读了 ngram 分词器。对于当前用例,最小长度 3 就足够了。有什么具体/通用的方法吗?就像在 mongodb 中一样,我使用了正则表达式。
  • 您可以使用query_stringwildcard 搜索。如果您确实使用wildcard,您可能希望针对关键字运行它。例如POST test_index/_doc/_search {"query": {"wildcard": {"content.keyword": {"value": "*xyz abc*"}}}} 请注意,使用 "content.keyword" 字段将使查询区分大小写。
  • 感谢您的回复。我试过这个。它仅适用于某些情况。但是“RegionLasit Pant0Q00B000001KBQ1SAO00”在这种情况下我使用 Lasit Pant 作为搜索词。它没有得到我的这份文件。
  • @LasitPant 您是否将* 用于通配符?本质上是您查询"*Lasit Pant*" 还是仅查询"Lasit Pant"
  • @LasitPant 对于wildcard 查询,您需要使用* 来涵盖该用例。或者,您仍然可以为此使用nGrams
【解决方案2】:

您也可以使用 type 参数来设置查询中的短语

 res = es.search(index=('indice_1'),

               body = {
    "_source":["content"],

    "query": {
        "query":"xyz abc"
        },
        type:"phrase"}

   ,
size=500,
scroll='60s')

【讨论】:

  • @pratik- : 'phrase'}, TypeError('keys must be str, int, float, bool or None, not type',)) 我明白了使用 ES 6.4
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多