【问题标题】:Elasticsearch - Nested value query inside field_value_factorElasticsearch - field_value_factor 内的嵌套值查询
【发布时间】:2017-02-08 00:09:23
【问题描述】:

我是 ES 新手,希望为用户创建可搜索的产品目录,但我无法找到对购买相同产品的不同用户进行编码的方法。

我有一个完整的产品索引,这些产品可能已被我使用嵌套表示的不同用户多次购买。有些产品为所有用户提供条目,有些则没有。

我需要创建搜索产品的能力,并让特定用户购买的产品获得比其他产品更高的分数。我的问题是我不知道如何在 field_value_factor 函数中提取此字段,因为它可能并不适用于所有产品。

到目前为止,我最接近的尝试(感谢 Val)是:

{
   "query": {
      "bool": {
         "should": [
            {
               "multi_match": {
                  "query": "black toner",
                  "fields": [
                     "name",
                     "description"
                  ],
                  "tie_breaker": 0.3
               }
            },
            {
               "query": {
                  "function_score": {
                     "query": {
                        "bool": {
                           "must": [
                              {
                                 "multi_match": {
                                    "query": "black toner",
                                    "fields": [
                                       "name",
                                       "description"
                                    ],
                                    "tie_breaker": 0.3
                                 }
                              },
                              {
                                 "nested": {
                                    "path": "user",
                                    "query": {
                                       "term": {
                                          "user.userid": "MWUser2"
                                       }
                                    }
                                 }
                              }
                           ]
                        }
                     },
                     "functions": [
                        {
                           "field_value_factor": {
                              "field": "user.count",
                              "modifier": "log1p",
                              "missing": 0
                           }
                        }
                     ]
                  }
               }
            }
         ]
      }
   }
}

这里的问题是我不能将nested``path 应用到field_value_factor,所以它总是显示为0,并且用户特定的得分提升不起作用。当nested``path 应用于整个function_score 时,descriptionname 上的第一个multi_match 查询不起作用。

编辑 1

另一种方法是分别计算分数,然后将它们组合起来。我可以做到这一点,但 should 组合它们的方法会使分数正常化,这不是我想要的。因此,我没有做0.9 + 40.5 + 5,而是两者都得到0.7+0.7。有没有办法解决这个问题?

{ 
   "query": {
      "bool": {
         "should": [
            {
               "query": {
                  "multi_match": {
                      "use_dis_max": false, 
                     "query": "black super quality toner",
                     "fields": [
                        "name^3",
                        "description"
                     ],
                     "tie_breaker": 0.3
                  }
               }
            },
            {
               "query": {
                  "nested": {
                     "path": "user",
                     "query": {
                        "function_score": {
                           "filter": {
                              "term": {
                                 "user.userid": "MWUser1"
                              }
                           },
                           "functions": [
                              {
                                 "field_value_factor": {
                                    "field": "user.count",
                                    "modifier": "log1p",
                                    "missing": 0
                                 }
                              }
                           ]
                        }
                     }
                  }
               }
            }
         ]
      }
   }
}

我的映射是:

{
  "mappings": {
    "nest_type": {
      "properties": {
        "id" :             {"type":"string"},
        "company_code" :   {"type":"string"},
        "name" :           {"type":"string"},
        "description" :    {"type":"string"},
        "virtual_entity" : {"type":"boolean"},
        "created_at" :     {"type":"date"},
        "updated_at" :     {"type":"date"},
        "user": {
          "type": "nested",
          "properties": {
            "userid": {"type":"string"},
            "count": {"type":"short"},
            "last_bought": {"type":"date"}
          } 
        },
        "@timestamp" : {"type":"date"}
      }
    }
  }
}   

一些文件是:

{
  "id": "C8061X",
  "company_code": "MWCOMPCODE",
  "name": "Black LaserJet Toner Cartridge",
  "description": "- HP LaserJet C8061 Family Print Cartridges deliver extra sharp black text, smooth greyscales and fine detail in graphics.\n- HP LaserJet C8061 Family Print Cartridges with Smart Printing Technology with in-built reliability and rigorous quality testing ensure maximum printer uptime with minimum user intervention.\n- HP LaserJet C8061 Family Print Cartridges all-in-one design allow effortless installation and maintenance. Smart Printing Technology features monitoring of supplies status and usage information via the printers control panel or web browser.\n",
  "virtual_entity": false,
  "created_at": "2016-09-21T12:23:53.000Z",
  "updated_at": "2016-09-21T12:23:53.000Z",
  "user": [
    {
      "userid": "MWUser1",
      "count": 4,
      "last_bought": "2016-09-14T12:43:30.000Z"
    },
    {
      "userid": "MWUser2",
      "count": 2,
      "last_bought": "2016-09-14T10:00:00.000Z"
    }
  ],
  "@timestamp": "2016-09-21T13:38:30.077Z"
}
{
  "id": "C8061Y",
  "company_code": "MWCOMPCODE",
  "name": "Black LaserJet Toner Cartridge Super Quality",
  "description": "- HP LaserJet C8061 Family Print Cartridges deliver extra quality sharp black text, smooth greyscales and fine detail in graphics.\n- HP LaserJet C8061 Family Print Cartridges with Smart Printing Technology with in-built reliability and rigorous quality testing ensure maximum printer uptime with minimum user intervention.\n- HP LaserJet C8061 Family Print Cartridges all-in-one design allow effortless installation and maintenance. Smart Printing Technology features monitoring of supplies status and usage information via the printers control panel or web browser.\n",
  "virtual_entity": false,
  "created_at": "2016-09-21T12:23:53.000Z",
  "updated_at": "2016-09-21T12:23:53.000Z",
  "@timestamp": "2016-09-21T13:38:30.077Z"
}

【问题讨论】:

    标签: elasticsearch nested


    【解决方案1】:

    我最终做了以下事情。我确保文档满足全文搜索,并将分数建立为全文分数和用户计数日志的增强组合。

    GET /nest_index_toy/_search
    {
       "query": {
          "bool": {
             "must": {
                "multi_match": {
                   "use_dis_max": false,
                   "query": "black toner super quality",
                   "fields": [
                      "name^3",
                      "description"
                   ],
                   "tie_breaker": 0.3,
                   "boost": 2
                }
             },
             "should": [
                {
                   "multi_match": {
                      "use_dis_max": false,
                      "query": "black toner super quality",
                      "fields": [
                         "name^3",
                         "description"
                      ],
                      "tie_breaker": 0.3,
                      "boost": 2
                   }
                },
                {
                   "nested": {
                      "path": "user",
                      "query": {
                         "function_score": {
                            "filter": {
                               "term": {
                                  "user.userid": "MWUser1"
                               }
                            },
                            "functions": [
                               {
                                  "field_value_factor": {
                                     "field": "user.count",
                                     "modifier": "log1p",
                                     "missing": 0
                                  }
                               }
                            ]
                         }
                      }
                   }
                }
             ]
          }
       }
    }
    

    【讨论】:

      【解决方案2】:

      您首先需要将嵌套用户的条件构建到 nested 查询中,然后包装您的 function_score 查询:

      {
        "query": {
          "nested": {
            "path": "user",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "user.userid": "MWUser1"
                    }
                  },
                  {
                    "function_score": {
                      "query": {
                        "multi_match": {
                          "query": "black toner",
                          "fields": [
                            "name",
                            "description"
                          ],
                          "tie_breaker": 0.3
                        }
                      },
                      "field_value_factor": {
                        "field": "user.userid.count",
                        "modifier": "log1p",
                        "missing": 10
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "size": 5
      }
      

      【讨论】:

      • 感谢您的回复,我不知道您可以在 function_score 中进行查询,但这并不能满足我的要求。使用“必须”时,不返回任何结果。当我使用“应该”时,仅返回具有“MWUser1”条目的文档,但未使用他的count 值。当使用“MWUser2”重新运行查询时,“C8061X”文档获得相同的分数,但 MWUser2.count 是 2 而不是 4。如果此查询只能基于所选用户 count 返回分数,那么我想我可以结合其他查询做全文匹配吗?
      • 嗯,可能namedescription 上的multi_match 查询需要在顶层提取到bool/must。可以试试吗?
      • 啊-谢谢。我将multi_match 复制到顶层并使用should 这个查询返回没有任何user 信息的产品,user 以前购买的产品位于顶部。但是,它看起来像是采用“第一个”user.count 而不是选定的。知道如何调试/检查查询在做什么吗?
      • 使用bool/must 而不是bool/should。也可以用您现在的查询更新您的问题
      • @StevenOxley - 我正在使用 v2.4.0 并且能够执行 nested { .. query{ function_score @Val - 在 nested 查询中无法引用外部字段,因此我无法执行 @987654339 @。我有两个单独的查询:1)全文分数和 2)MWUser1 的分数=计数。可以只添加这些 _scores 吗?使用should 规范化每个子查询的分数,所以不是做0.9 + 40.5 + 10 它做0.7 +0.7 = 1.40.7+0.7=1.4
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      • 2018-03-08
      • 2018-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多