如何在Elasticsearch中使用无痛脚本获取数组字段的匹配字段值?

马皮

我正在使用Elasticsearch 7.6

我在餐厅索引中有如下文档:

  "name" : "ABC restaurant",
  "menu" : [
    {
      "name" : "chicken",
      "count" : 23
    },
    {
      "name" : "rice",
      "count" : 10        }
   ]

计数是指收到的订单数。

当客户按网站上的菜单名称进行搜索时,我想给一家餐厅中菜单数很高的餐厅打出高分,并将其显示在搜索结果的顶部。

为此,似乎有必要了解无痛脚本中每个文档中的匹配菜单。

我想知道是否有可能。如果是这样,我该怎么办?


更新感谢您的回答@jaspreet chahal

我做了这样的索引:

PUT restaurant
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "menu":{
        "type": "nested", 
        "properties": {
          "name": {"type": "text"},
          "count": {"type": "integer"}
        }
      }
    }
  }
}

POST /restaurant/_doc/1
{
  "name": "ABC Restaurant",
  "menu": [
    {"name": "chicken", "count": 3},
    {"name": "cake", "count": 5}
  ]
}

POST /restaurant/_doc/2
{
  "name": "TEST Restaurant",
  "menu": [
    {"name": "chicken", "count": 10},
    {"name": "cake", "count": 7},
    {"name": "rice", "count": 2}
  ]
}


POST /restaurant/_doc/3
{
  "name": "Good Restaurant",
  "menu": [
    {"name": "chicken", "count": 20},
    {"name": "cake", "count": 13},
    {"name": "rice", "count": 5}
  ]
}

我想做的是在使用多重匹配时根据匹配的菜单数获得总分,如下所示:

GET restaurant/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "function_score": {
            "query": {
              "bool": {
                "must": [
                  {
                    "multi_match": {
                      "query": "chicken",
                      "type": "cross_fields",
                      "fields": [
                        "menu.name", 
                        "name"
                      ],
                      "operator": "and"
                    }
                  }
                ]
              }
            },
            "boost_mode": "replace",
            "functions": [
              {
                "field_value_factor": {
                  "field": "menu.count",
                  "missing": 0
                }
              }
            ]
          }
        }
      ]
    }
  }
}

但是上面的查询没有任何结果。

为了使其工作,我在菜单映射中添加了“ include_in_root:True”。但是在这种情况下,我得不到适当的分数。.(似乎无论搜索词如何,都获得了菜单数的最低分数)

请问如何使这项工作符合我的期望?谢谢 !


再次更新。

我向您的查询添加了多匹配项

GET restaurant/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "query": "Good Restaurant chicken", 
            "type": "cross_fields", 
            "fields": [
              "menu.name",
              "name"
            ]
          }
        },
        {
          "nested": {
            "path": "menu",
            "query": {
              "function_score": {
                "query": {
                  "bool": {
                    "should": [
                      {
                        "match": {
                          "menu.name": {
                            "query": "Good Restaurant chicken",
                            "operator": "or"
                          }
                        }
                      }
                    ]
                  }
                },
                "boost_mode": "replace",
                "functions": [
                  {
                    "field_value_factor": {
                      "field": "menu.count",
                      "missing": 0
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

一切顺利!但是分数受到多重匹配查询的影响。

这是查询的结果:

  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 21.11436,
    "hits" : [
      {
        "_index" : "restaurant",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 21.11436,
        "_source" : {
          "name" : "Good Restaurant",
          "menu" : [
            {
              "name" : "chicken",
              "count" : 20
            },
            {
              "name" : "cake",
              "count" : 13
            },
            {
              "name" : "rice",
              "count" : 5
            }
          ]
        }
      },
      {
        "_index" : "restaurant",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 10.133532,
        "_source" : {
          "name" : "TEST Restaurant",
          "menu" : [
            {
              "name" : "chicken",
              "count" : 10
            },
            {
              "name" : "cake",
              "count" : 7
            },
            {
              "name" : "rice",
              "count" : 2
            }
          ]
        }
      },
      {
        "_index" : "restaurant",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 3.1335313,
        "_source" : {
          "name" : "ABC Restaurant",
          "menu" : [
            {
              "name" : "chicken",
              "count" : 3
            },
            {
              "name" : "cake",
              "count" : 5
            }
          ]
        }
      }
    ]
  }
}

非常感谢您的回答 :)

贾斯普雷特·查哈尔(Jaspreet Chahal)

您可以使用function_score根据计数值为嵌套文档赋予更高的分数。

查询:

{
  "query": {
    "nested": {
      "path": "menu",
      "query": {
        "function_score": {
          "score_mode": "sum",
          "boost_mode": "replace",
          "query": {
            "match": {
              "menu.name": "chicken"
            }
          },
          "functions": [
            {
              "field_value_factor": {
                "field": "menu.count"
              }
            }
          ]
        }
      }
    }
  }
}

结果:

"hits" : [
      {
        "_index" : "index63",
        "_type" : "_doc",
        "_id" : "tA8IPHIBzLrvZDnz-ghE",
        "_score" : 23.0,
        "_source" : {
          "name" : "ABC restaurant",
          "menu" : [
            {
              "name" : "chicken",
              "count" : 23
            },
            {
              "name" : "rice",
              "count" : 10
            }
          ]
        }
      },
      {
        "_index" : "index63",
        "_type" : "_doc",
        "_id" : "tQ8JPHIBzLrvZDnz-AiA",
        "_score" : 20.0,
        "_source" : {
          "name" : "XYZ restaurant",
          "menu" : [
            {
              "name" : "chicken",
              "count" : 20
            },
            {
              "name" : "rice",
              "count" : 8
            }
          ]
        }
      }
    ]

Edit1:对于嵌套字段,您需要使用嵌套查询,不能直接在这些字段上运行搜索。

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": {
              "operator": "and",
              "query": "chicken"
            }
          }
        },
        {
          "nested": {
            "path": "menu",
            "query": {
              "function_score": {
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "menu.name": {
                            "query": "chicken",
                            "operator": "and"
                          }
                        }
                      }
                    ]
                  }
                },
                "boost_mode": "replace",
                "functions": [
                  {
                    "field_value_factor": {
                      "field": "menu.count",
                      "missing": 0
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

Edit2:仅考虑嵌套查询的得分,您可以提高得分,以便使与嵌套得分匹配的文档得分更高。如果您不希望多重比赛获得任何分数。您可以将其放置在constant_score中,将其提升为0,与此匹配的文档将获得0分

{
  "query": {
    "bool": {
      "should": [
        {
          "constant_score": {
            "filter": {
              "multi_match": {
                "query": "Good Restaurant chicken",
                "type": "cross_fields",
                "fields": [
                  "name"
                ]
              }
            },
            "boost": 0
          }
        },
        {
          "nested": {
            "path": "menu",
            "query": {
              "function_score": {
                "query": {
                  "bool": {
                    "should": [
                      {
                        "match": {
                          "menu.name": {
                            "query": "Good Restaurant chicken",
                            "operator": "or"
                          }
                        }
                      }
                    ]
                  }
                },
                "boost_mode": "replace",
                "functions": [
                  {
                    "field_value_factor": {
                      "field": "menu.count",
                      "missing": 0
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Symfony2中使用jquery / Ajax从PHP文件中获取数组字段值?

来自分类Dev

如何在PostgreSQL中使用递归查询连接字段值?

来自分类Dev

如何在Elasticsearch中对相同字段进行精确值匹配查询?

来自分类Dev

如何在Elasticsearch中使用脚本比较字段并删除字段?

来自分类Dev

Elasticsearch将嵌套字段与值数组匹配

来自分类Dev

如何在Jquery中使用类获取和放置这些特定字段的值

来自分类Dev

如何在Elasticsearch过滤器脚本中使用嵌套字段

来自分类Dev

如何在elasticsearch中获取空字段?

来自分类Dev

如何在Django的子模型字段中使用抽象模型字段值作为默认值?

来自分类Dev

如何在bash中使用awk遍历字段的多个值?

来自分类Dev

如何在Elasticsearch中基于输入字段获取字段的总和值(输入字段和总和输出字段不同)

来自分类Dev

如何在要在Google DataStudio中使用的应用程序脚本高级服务中指定数组字段?

来自分类Dev

如何在CRM 2011中使用Javascript和oData获取PartyList字段的值

来自分类Dev

如何在Symfony2中使用jquery / Ajax从PHP文件中获取数组字段值?

来自分类Dev

Postgres:如何在子查询中使用字段的值

来自分类Dev

如何在Elasticsearch中使用脚本比较字段并删除字段?

来自分类Dev

如何在弹性脚本中使用特殊文档字段?

来自分类Dev

PostgreSQL-在结果中获取数组字段的匹配值

来自分类Dev

如何在ElasticSearch中使用脚本更新数组类型的字段?

来自分类Dev

如何在elasticsearch的索引字段中使用不查询

来自分类Dev

如何在Elasticsearch 5.1中获取指定字段(使用curl)?

来自分类Dev

Elasticsearch Painless 脚本按值获取嵌套字段?

来自分类Dev

如何获取数组mongodb中的字段值

来自分类Dev

如何在 MySQL 中使用 case 获取特定字段的计数

来自分类Dev

如何在聚合中获取字段的值数组

来自分类Dev

如何在blade.php中使用vue获取字段的旧值

来自分类Dev

如何在 tkinter for python 中使用迭代创建输入字段和按钮以从输入字段获取内容?

来自分类Dev

如何在 Laravel 中使用 eloquent 使用包含在数组字段中的搜索值

来自分类Dev

如何在 elasticsearch 中获取嵌套字段的不同值?

Related 相关文章

  1. 1

    如何在Symfony2中使用jquery / Ajax从PHP文件中获取数组字段值?

  2. 2

    如何在PostgreSQL中使用递归查询连接字段值?

  3. 3

    如何在Elasticsearch中对相同字段进行精确值匹配查询?

  4. 4

    如何在Elasticsearch中使用脚本比较字段并删除字段?

  5. 5

    Elasticsearch将嵌套字段与值数组匹配

  6. 6

    如何在Jquery中使用类获取和放置这些特定字段的值

  7. 7

    如何在Elasticsearch过滤器脚本中使用嵌套字段

  8. 8

    如何在elasticsearch中获取空字段?

  9. 9

    如何在Django的子模型字段中使用抽象模型字段值作为默认值?

  10. 10

    如何在bash中使用awk遍历字段的多个值?

  11. 11

    如何在Elasticsearch中基于输入字段获取字段的总和值(输入字段和总和输出字段不同)

  12. 12

    如何在要在Google DataStudio中使用的应用程序脚本高级服务中指定数组字段?

  13. 13

    如何在CRM 2011中使用Javascript和oData获取PartyList字段的值

  14. 14

    如何在Symfony2中使用jquery / Ajax从PHP文件中获取数组字段值?

  15. 15

    Postgres:如何在子查询中使用字段的值

  16. 16

    如何在Elasticsearch中使用脚本比较字段并删除字段?

  17. 17

    如何在弹性脚本中使用特殊文档字段?

  18. 18

    PostgreSQL-在结果中获取数组字段的匹配值

  19. 19

    如何在ElasticSearch中使用脚本更新数组类型的字段?

  20. 20

    如何在elasticsearch的索引字段中使用不查询

  21. 21

    如何在Elasticsearch 5.1中获取指定字段(使用curl)?

  22. 22

    Elasticsearch Painless 脚本按值获取嵌套字段?

  23. 23

    如何获取数组mongodb中的字段值

  24. 24

    如何在 MySQL 中使用 case 获取特定字段的计数

  25. 25

    如何在聚合中获取字段的值数组

  26. 26

    如何在blade.php中使用vue获取字段的旧值

  27. 27

    如何在 tkinter for python 中使用迭代创建输入字段和按钮以从输入字段获取内容?

  28. 28

    如何在 Laravel 中使用 eloquent 使用包含在数组字段中的搜索值

  29. 29

    如何在 elasticsearch 中获取嵌套字段的不同值?

热门标签

归档