Python ElasticSearch查询显示多重匹配的误报

时间:2018-08-12 17:44:53

标签: python-3.x elasticsearch full-text-search elasticsearch-dsl-py

尝试使用带有ElasticSearch和python的csv数据集为最终用户创建具有全文搜索功能的最终用户可搜索的仪表板。

搜索将返回相关csv行的行索引。有多个列,即_id, topic

如果我尝试在数据集中查询"cyber security"。我得到的大多数结果都包含单词"cyber security""cyber-security",但返回的其他行涉及粮食安全和军队安全。 对于一般的搜索字词,如何避免这种情况?

此外,搜索词“ cyber”或“ "cyber security"”未选择包含诸如“ "cybersecurity""cybernetics"”之类的单词的主题

我将如何写一个可以捕获这些条件的条件? 请记住,这也需要以其他方式进行,即,如果我搜索"food security",则不应出现网络主题。

def test_search():
    client = Elasticsearch()
    q = Q("multi_match", query='cyber security',
          fields=['topic'],
          operator='or')
    s = Search(using=client, index="csvfile").query(q) \

    # .filter('term', name="food")
    # .exclude("match", description="beta")

编辑:根据评论中的要求添加示例需求

csv文件可以如下所示。

_id,topic
1,food security development in dairy
2,securing hungry people by providing food
3,cyber security in army
4,bio informatics for security
5,cyber security in the world
6,food security in the world
7,cyberSecurity in world
8,army security in asia
9,cybernetics in the world
10,cyber security in the food industry.
11,cyber-information
12,cyber security 
13,secure secure army man
14,crytography for security
15,random stuff

可接受

搜索词为cyber-> 3,5,7,9,10,11,12
搜索词是security->除11,14,15以外的所有内容
搜索词为cyber securitycybersecurity-> 3,5,7,9,10,11,12(在这种情况下,网络需要具有更高的优先级,用户对其他安全性将不感兴趣类型)
搜索词是food security-> 1,2

完美案例
搜索词是cybercyber securitycybersecurity-> 3,4,5,7,9,10,11,12,14

考虑到密码学和生物信息学在很大程度上与网络安全有关,我是否应该使用文档集群来实现这一目标(机器学习技术)?

1 个答案:

答案 0 :(得分:1)

这是正常的“全文本”搜索行为。在Elasticsearch中,文本字段为analysed。标准分析器仅对字符串进行标记化,然后将所有标记转换为小写,然后再将其添加到反向索引中。当您为"food security""cyber security""cyber-security""army security""cybersecurity""cybernetics"编制索引时,反向索引看起来像这样:

"food" -> ["food security"]
"cyber" -> ["cyber security", "cyber-security"]
"army" -> ["army security"]
"security" -> ["food security", "cyber security", "cyber-security", "army security"]
"cybersecurity" -> ["cybersecurity"]
"cybernetics" -> ["cybernetics"]

然后,当您搜索"food security"时,搜索字符串将分析为["food", "security"]"food""security"的倒排索引中的所有条目都将匹配,即:["food security", "cyber security", "cyber-security", "army security"]。另一方面,对"cybersecurity"的搜索将仅与"cybersecurity"匹配。


编辑:即将解决

您的要求中有几个不同的“功能”:

  • security必须与securesecuring匹配。这可以通过english analyzer来实现,它将所有单词的所有变体形式组合在一起。
  • cybersecurity必须与cybercybernetics等匹配。这可以通过ngram analyser
  • 来实现。
  • 搜索cyber security时,与food security不匹配。可以使用 common terms queries 设置适当的cutoff_frequency
  • 来实现
  • 匹配语义上接近的单词(例如“网络安全”和“密码学”)。据我所知,这无法通过Elasticsearch实现。

将所有内容组合在一起,我们可以得出以下映射(有关自定义映射的说明,请参见this post

{
  "mappings": {
    "_doc": {
      "properties": {
        "id": {
          "type": "keyword",
          "ignore_above": 256
        },
        "topic": {
          "type": "text",
          "analyzer": "english",
          "fields": {
            "fourgrams": {
              "type": "text",
              "analyzer": "fourgrams"
            }
          }
        }
      }
    }
  },
  "settings": {
    "analysis": {
      "filter": {
        "fourgrams_filter": {
          "type": "ngram",
          "min_gram": 4,
          "max_gram": 4
        }
      },
      "analyzer": {
        "fourgrams": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "fourgrams_filter"
          ]
        }
      }
    }
  }
}

以及以下搜索查询

GET topics/_search 
{
  "size": 20,
  "query": {
    "bool": {
      "should": [
        {
          "common": {
            "topic": {
              "query": "cyber security",
              "cutoff_frequency": 0.3,
              "boost": 2
            }
          }
        },
        {
          "match": {
            "topic.fourgrams": "cyber security"
          }
        }
      ]
    }
  }
}

您仍然会有假阴性,但是希望可以按照预期的顺序对它们进行排序,以便您可以过滤出较低的分数。