代码之家  ›  专栏  ›  技术社区  ›  Bren

Elasticsearch如何匹配字段标记是查询标记子集的文档

  •  1
  • Bren  · 技术社区  · 10 年前

    我有一个关键字/关键短语字段,我使用标准分析器进行标记。如果搜索短语中包含该字段的所有标记,我希望该字段匹配。

    例如,如果字段值为“veni,vidi,vici”,搜索短语为“Ceaser veni,vidi,vici”我希望此搜索短语匹配,但搜索短语“veni、vidi”不匹配。

    我还需要“vidi,veni,vici”(奇怪!)以匹配。因此,术语的位置和顺序并不重要。我认为短语匹配对我来说不太合适。

    我可以在这个特定示例中使用“bool query”和“minimum_should_match”参数,但这并不是我真正想要的,因为最小值应该匹配的是搜索短语中标记的比率/数量。

    2 回复  |  直到 10 年前
        1
  •  2
  •   ChintanShah25    10 年前

    纯ES解决方案将是这样的。你需要两个请求。

    1) 首先,您需要传递用户查询 analyze api 获取所有搜索令牌。

    curl -XGET 'localhost:9200/_analyze' -d '
    {
      "analyzer" : "standard",
      "text" : "Ceaser veni,vidi,vici"
    }'
    

    你会得到4个代币 停止 , 鹿肉 , 视频显示器 , vici公司 。您需要将这些标记作为数组传递给下一个 search 要求

    2) 我们需要搜索令牌为 子集 搜索令牌的数量。

    {
      "query": {
        "filtered": {
          "filter": {
            "bool": {
              "must": [
                {
                  "query": {
                    "match": {
                      "title": "Ceaser veni,vidi,vici"
                    }
                  }
                },
                {
                  "script": {
                    "script": "if(search_tokens.containsAll(doc['title'].values)){return true;}",
                    "params": {
                      "search_tokens": [
                        "ceaser",
                        "veni",
                        "vidi",
                        "vici"
                      ]
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
    

    这里是第一份工作 match query 过滤器内部是缩小脚本应该运行的文档的范围。 containsAll 方法将检查文档标记是否 sublist 搜索令牌的数量。这将很慢,但可以用当前设置完成任务。您可以做的一大改进是将令牌存储为数组,以便 doc['title'].values 可以替换为将改进脚本的字段。

    希望这有帮助!

        2
  •  0
  •   sean    10 年前

    没有内置解决方案,但它可以工作:

    1. 在每个文档的字段中添加一个额外的字段,其中包含术语的数量。因此,在您的“veni,vidi,vici”示例中,您将有一个类似于“field_term_count”的字段:3。

    2. 对搜索查询中的每个标记执行单独的匹配搜索。

    3. 将与至少一个匹配项(例如,具有文档ID键和计数值的哈希表)匹配的每个文档的搜索次数相加。

    4. 将3中的匹配数与每个匹配文档的“field_term_count”字段进行比较。如果它们相等,则文档是匹配的。

    然后,“Ceaser veni,vidi,vici”将匹配,但搜索短语“veni,vidi”将不匹配。对于合理数量的比赛,速度应该相当快。