【问题标题】:How to score by max relevance match in array elements in ElasticSearch?如何通过 ElasticSearch 中数组元素中的最大相关匹配来评分?
【发布时间】:2016-12-06 01:32:20
【问题描述】:

我有一个字段(“关键字”)的自动完成分析器。该字段是一个字符串数组。当我使用搜索字符串进行查询时,我想首先显示数组关键字的单个元素最匹配的文档。问题是如果字符串的一部分与数组“keywords”的更多元素匹配,那么这个文档会出现在另一个匹配更少但更好的文档之前。例如,如果我有一个包含“加油站”一词的查询,则返回文档的关键字如下:

"hits": [
  {
    "_index": "locali_v3",
    "_type": "categories",
    "_id": "5810767ddc536a03b4761acd",
    "_score": 3.1974547,
    "_source": {
      "keywords": [
        "Radio Station",
        "Radio Station"
      ]
    }
  },
  {
    "_index": "locali_v3",
    "_type": "categories",
    "_id": "581076d8dc536a03b4761cc3",
    "_score": 3.0407648,
    "_source": {
      "keywords": [
        "Stationery Store",
        "Stationery Store"
      ]
    }
  },
  {
    "_index": "locali_v3",
    "_type": "categories",
    "_id": "5810767ddc536a03b4761ace",
    "_score": 2.903595,
    "_source": {
      "keywords": [
        "TV Station",
        "TV Station"
      ]
    }
  },
  {
    "_index": "locali_v3",
    "_type": "categories",
    "_id": "581076cddc536a03b4761c87",
    "_score": 2.517158,
    "_source": {
      "keywords": [
        "Praktoreio Ugrwn Kausimwn/Gkaraz",
        "Praktoreio Ygrwn Kaysimwn/Gkaraz",
        "Praktoreio Ugron Kausimon/Gkaraz",
        "Praktoreio Ygron Kaysimon/Gkaraz",
        "Πρακτορείο Υγρών Καυσίμων/Γκαράζ",
        "Gas Station"
      ]
    }
}

“加油站”排在第四位,虽然它的单元素匹配最好。有没有办法告诉 ElasticSearch 我不在乎关键字中出现了多少次“gas”或“station”?我希望数组关键字的最大元素匹配作为得分因子。

我的设置是:

{
  "locali": {
    "settings": {
      "index": {
        "creation_date": "1480937810266",
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "edge_ngram",
          "min_gram": "1",
          "max_gram": "20"
        }
      },
      "analyzer": {
        "keywords": {
          "filter": [
            "lowercase",
            "autocomplete_filter"
          ],
          "char_filter": [
            "my_char_filter"
          ],
          "type": "custom",
          "tokenizer": "standard"
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": [
            "ί => ι",
            "Ί => Ι",
            "ή => η",
            "Ή => Η",
            "ύ => υ",
            "Ύ => Υ",
            "ά => α",
            "Ά => Α",
            "έ => ε",
            "Έ => Ε",
            "ό => ο",
            "Ό => Ο",
            "ώ => ω",
            "Ώ => Ω",
            "ϊ => ι",
            "ϋ => υ",
            "ΐ => ι",
            "ΰ => υ"
          ]
        }
      }
    },
    "number_of_shards": "1",
    "number_of_replicas": "1",
    "uuid": "TJjOt9L9QE2HrsUFHM6zJg",
    "version": {
      "created": "2040099"
    }
  }
}
  }
}

还有映射:

{
  "locali": {
"mappings": {
  "places": {
    "properties": {
      "formattedCategories": {
        "properties": {
          "english": {
            "type": "string"
          },
          "greek": {
            "type": "string"
          }
        }
      },
      "keywords": {
        "type": "string",
        "analyzer": "keywords"
      },
      "loc": {
        "properties": {
          "coordinates": {
            "type": "geo_point"
          }
        }
      },
      "location": {
        "properties": {
          "formattedAddress": {
            "properties": {
              "english": {
                "type": "string"
              },
              "greek": {
                "type": "string"
              }
            }
          },
          "locality": {
            "properties": {
              "english": {
                "type": "string"
              },
              "greek": {
                "type": "string"
              }
            }
          },
          "neighbourhood": {
            "properties": {
              "english": {
                "type": "string"
              },
              "greek": {
                "type": "string"
              }
            }
          }
        }
      },
      "name": {
        "properties": {
          "english": {
            "type": "string"
          },
          "greek": {
            "type": "string"
          }
        }
      },
      "rating": {
        "properties": {
          "rating": {
            "type": "long"
          }
        }
      },
      "seenDetails": {
        "type": "long"
      },
      "verified": {
        "type": "long"
      }
    }
  },
  "regions": {
    "properties": {
      "keywords": {
        "type": "string",
        "analyzer": "keywords"
      },
      "loc": {
        "properties": {
          "coordinates": {
            "type": "geo_point"
          }
        }
      },
      "name": {
        "properties": {
          "english": {
            "type": "string"
          },
          "greek": {
            "type": "string"
          }
        }
      },
      "type": {
        "type": "long"
      },
      "weight": {
        "type": "long"
      }
    }
  },
  "categories": {
    "properties": {
      "keywords": {
        "type": "string",
        "analyzer": "keywords"
      },
      "name": {
        "properties": {
          "english": {
            "type": "string"
          },
          "greek": {
            "type": "string"
          }
        }
      },
      "weight": {
        "type": "long"
      }
    }
  }
}
  }
}

【问题讨论】:

  • 你能把你的映射和设置也粘贴到这里吗?

标签: arrays elasticsearch


【解决方案1】:

您能否在此处发布您也在此处尝试的查询。 我使用以下查询尝试了您的示例

{
  "query": {"match": {
    "keywords": "gas station"
    }
  }
}

我得到了你想要的结果。

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 0.081366636,
    "hits": [
      {
        "_index": "stack",
        "_type": "type",
        "_id": "AVjP6QnpdNp-z_ybGd-L",
        "_score": 0.081366636,
        "_source": {
          "keywords": [
            "Praktoreio Ugrwn Kausimwn/Gkaraz",
            "Praktoreio Ygrwn Kaysimwn/Gkaraz",
            "Praktoreio Ugron Kausimon/Gkaraz",
            "Praktoreio Ygron Kaysimon/Gkaraz",
            "Πρακτορείο Υγρών Καυσίμων/Γκαράζ",
            "Gas Station"
          ]
        }
      },
      {
        "_index": "stack",
        "_type": "type",
        "_id": "AVjP5-u5dNp-z_ybGd-I",
        "_score": 0.03182549,
        "_source": {
          "keywords": [
            "Radio Station",
            "Radio Station"
          ]
        }
      },
      {
        "_index": "stack",
        "_type": "type",
        "_id": "AVjP6KiKdNp-z_ybGd-K",
        "_score": 0.03182549,
        "_source": {
          "keywords": [
            "TV Station",
            "TV Station"
          ]
        }
      }
    ]
  }
}

试试这个查询,看看你是否得到了想要的结果。如果这对您不起作用,您也可以回复您的映射、查询和 ES 版本。

希望这能解决您的问题。谢谢

【讨论】:

  • 我有一个名为“关键字”的自动完成分析器。我正在使用相同的查询,但结果是我上面描述的。
  • 好的。尝试解释 api 以了解为什么它与分析器得分不同,还尝试检查该分析器生成的分析术语存储在倒排索引中。
  • 我环顾四周,它的出现是因为倒排索引上的 tdf/idf 值不同,因为您在映射中使用了 edge-ngram 标记器。所以这个 tdf 和 idf 负责对前 3 个文档进行更多的提升。
  • 试试这些stackoverflow.com/questions/33208587/…elastic.co/guide/en/elasticsearch/guide/current/…,你可以忽略这些因素或者去掉edge n gram
猜你喜欢
  • 2013-11-12
  • 2017-01-28
  • 2016-07-05
  • 1970-01-01
  • 2015-12-06
  • 2021-08-03
  • 1970-01-01
  • 2014-12-25
  • 2012-12-02
相关资源
最近更新 更多