【问题标题】:Elasticsearch match one array with another arrayElasticsearch 将一个数组与另一个数组匹配
【发布时间】:2020-03-30 20:40:35
【问题描述】:

假设我有两个索引 kidsoutings_for_kids 具有以下数据

  • 孩子们
[
  {
    "name": "little kid 1",
    "i_like":["drawing","teddybears"]
  },

]
  • 儿童郊游
[
  {
    "name": "Teddybear drawing fights with apples!",
    "for_kids_that_like":["apples","teddybears","drawing", "play outside games"]
  },
  {
    "name": "drawing and teddies!",
    "for_kids_that_like":["teddybears","drawing"]
  }
]

我想找一个和小孩子 1 喜欢的东西一样的郊游,如果有更多的话,分数会更低。

小孩子 1 不应该 100% 匹配第一次郊游。它有小孩 1 想要的东西,但它有更多,例如苹果,它应该匹配 50%。 它应该 100% 与第二次郊游相匹配。

【问题讨论】:

  • 当你说匹配 50% 时,你的意思是分数应该正好是一半?示例顶击应该得到 100,其余为 50。
  • 以下查询能解决您的问题吗?

标签: elasticsearch elasticsearch-dsl elasticsearch-query


【解决方案1】:

这将是一个两步过程:

  1. 从字段索引中获取 i_like 值
  2. 使用步骤 1 中的 i_like 查询外出索引

    1. 使用术语查询来匹配每个值
    2. 使用脚本比较数组大小和值的数量
    3. 使用常数分数根据索引计数给出相同的分数

查询

GET outings/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "constant_score": {
            "filter": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "for_kids_that_like": {
                        "value": "teddybears"
                      }
                    }
                  },
                  {
                    "term": {
                      "for_kids_that_like": {
                        "value": "drawing"
                      }
                    }
                  },
                  {
                    "script": {
                      "script": "doc['for_kids_that_like.keyword'].size()==2" --> replace 2 with size of elements searched
                    }
                  }
                ]
              }
            },
            "boost": 100
          }
        },
        {
          "constant_score": {
            "filter": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "for_kids_that_like": {
                        "value": "teddybears"
                      }
                    }
                  },
                  {
                    "term": {
                      "for_kids_that_like": {
                        "value": "drawing"
                      }
                    }
                  },
                  {
                    "script": {
                      "script": "doc['for_kids_that_like.keyword'].size()>2"
                    }
                  }
                ]
              }
            },
            "boost": 50
          }
        }
      ]
    }
  }
}

结果:

"hits" : [
      {
        "_index" : "outings",
        "_type" : "_doc",
        "_id" : "IH7tVHEBbLcSRUWr6wPj",
        "_score" : 100.0,
        "_source" : {
          "name" : "Teddybear drawing fights with apples!",
          "for_kids_that_like" : [
            "teddybears",
            "drawing"
          ]
        }
      },
      {
        "_index" : "outings",
        "_type" : "_doc",
        "_id" : "IX7zVHEBbLcSRUWrhgM9",
        "_score" : 50.0,
        "_source" : {
          "name" : "Teddybear drawing fights with apples!",
          "for_kids_that_like" : [
            "teddybears",
            "drawing",
            "apples"
          ]
        }
      }
    ]

如果您只想在顶部显示完全匹配的文档,然后是部分匹配,那么您不需要恒定分数(必须使用术语搜索进行查询)。默认情况下,完全匹配的分数更高

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-31
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多