Elasticsearch - 在函数分数中使用嵌套对象值

时间:2017-09-11 06:02:29

标签: elasticsearch scoring

我目前在ES中有一个嵌套对象interest_scores,如下所示:

[{
    username: 'Somebody',
    interest_scores: [
        { name: 'Running', score: 10 }
        { name: 'Food and drinks', score: 21 }
    ]
},
{
    username: 'SomebodyElse',
    interest_scores: [
        { name: 'Running', score: 7 }
        { name: 'Food and drinks', score: 29 }
    ]
}]

当我输入搜索字词正在运行时,我希望正在运行score位置最高的用户首先返回。

我知道这样做的方法是使用Function Score Query,但我不确定如何在函数/脚本中使用匹配的搜索词。我认为该查询将返回所有感兴趣的文档" Running"然后我可以使用interest_scores.{match}.score之类的东西来添加或乘以文档分数。

非常感谢任何帮助!

根据要求,这是映射:



{
  "influencers": {
    "mappings": {
      "influencer": {
        "properties": {
          "email": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "gender": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "geo": {
            "type": "geo_point"
          },
          "hashtags": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "id": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "interest_scores": {
            "type": "nested",
            "properties": {
              "name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "score": {
                "type": "long"
              }
            }
          },
          "interests": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "language": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "location": {
            "properties": {
              "city": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "country": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "country_code": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "lat": {
                "type": "float"
              },
              "lng": {
                "type": "float"
              },
              "state_code": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "subdivision": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "network_data": {
            "properties": {
              "facebook": {
                "properties": {
                  "url": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "username": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  }
                }
              },
              "instagram": {
                "properties": {
                  "bio": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "engagement": {
                    "type": "float"
                  },
                  "id": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "picture": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "reach": {
                    "type": "long"
                  },
                  "url": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "username": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  }
                }
              },
              "pinterest": {
                "properties": {
                  "url": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "username": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  }
                }
              },
              "twitter": {
                "properties": {
                  "bio": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "engagement": {
                    "type": "float"
                  },
                  "id": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "picture": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "reach": {
                    "type": "long"
                  },
                  "url": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "username": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  }
                }
              },
              "youtube": {
                "properties": {
                  "bio": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "engagement": {
                    "type": "float"
                  },
                  "id": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "picture": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "reach": {
                    "type": "long"
                  },
                  "url": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "username": {
                    "type": "text",
                    "fields": {
                      "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                      }
                    }
                  },
                  "videos": {
                    "type": "long"
                  },
                  "views": {
                    "type": "long"
                  },
                  "views_per_video": {
                    "type": "float"
                  }
                }
              }
            }
          },
          "networks": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "picture": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "total_reach": {
            "type": "long"
          },
          "username": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}




我还没有功能评分查询,我只在Kibana的Dev Tools中测试 - 我确实让所有其他过滤器正常工作。我只想说"如果搜索字词与interest_scores.name匹配,则按interest_scores.score

interest_scores.name对匹配进行排序

更新

当我在Kibana开发工具中测试它时,以下似乎正在起作用:



{
  "query": {
    "nested": {
      "path": "interest_scores",
      "score_mode": "sum",
      "query": {
        "function_score": {
          "query": {
              "match": { "interest_scores.name": "Running" }
          },
          "script_score": {
            "script": "_score + doc['interest_scores.score'].value"
          }
        }
      }
    }
  }
}




我已经使用一些不同的搜索词进行了测试,并且它总是首先返回最高分,但奇怪的是,当我删除script_score函数时,我得到相同的结果。任何人都可以告诉我这是一个很好的解决方案,或者为什么它没有script_score

1 个答案:

答案 0 :(得分:0)

如上所述here,您可以按嵌套字段排序:

{
  "_source": false,  # for inner hits - you can remove it
  "query": {
    "nested": {
      "path": "interest_scores",
      "filter": {
        "range": {
          "interest_scores.score": {
            "gte": "0"
          }
        }
      },
      "inner_hits": {}  # for inner hits - you can remove it
    }
  },
  "sort": {
    "interest_scores.score": {
      "order": "desc",
      "mode": "max",
      "nested_filter": {
        "range": {
          "interest_scores.score": {
            "gte": "0"
          }
        }
      }
    }
  }
}

*请注意,您可以使用inner_hits功能仅显示相关的嵌套文档。如果所有内部命中文档都相关 - 请删除标记的行。

**使用score字段或任何其他字段上的过滤条件(例如:您要过滤的name)。

编辑1: 如果您想获得特定名称的排序分数,请尝试:

{
  "_source": false,
  "query": {
    "nested": {
      "path": "interest_scores",
      "filter": {
        "term": {
          "interest_scores.name": "SCORE_NAME"
        }
      },
      "inner_hits": {}
    }
  },
  "sort": {
    "interest_scores.score": {
      "order": "desc",
      "mode": "max",
      "nested_filter": {
        "range": {
          "interest_scores.score": {
            "gte": "0"
          }
        }
      }
    }
  }
}

将所需的分数名称改为SCORE_NAME