代码之家  ›  专栏  ›  技术社区  ›  Mario Köhler

对术语查询性能和索引结构的总体见解

  •  1
  • Mario Köhler  · 技术社区  · 7 年前

    我最近第一次开始使用弹性搜索,我正在寻找一些见解/帮助。我对一个执行得不太好的术语查询有一个问题,这让我相信我的“划分”索引的方法可能不是最好的。我希望有人能对此有所了解。

    我需要进入弹性搜索的数据集由大约6000-7000万条记录组成。这些记录基本上是person+address+元数据记录,有两种明显的方法可以将它们划分/拆分为几个索引。我现在的做法是创建4个索引。这4个索引与数据集中包含的4种不同“类型”的记录相关联。将这四种类型想象为“客户账户”、“潜在客户”、“债务人”和“黑名单人员/地址”。这4个索引中的每个记录都与一家公司相关,我希望能够按“类型”和“公司”进行搜索。

    “按类型”很简单,我只需要处理与类型相关的索引。对于“按公司”部分,我开始使用这样的术语查询(这是一个布尔查询,因为它通常包含额外的搜索参数,为了简单/清晰起见,我在这里排除了这些参数):

    {
     "query": {
        "bool": {
          "filter": [{
              "term": { "company":  "MY COMPANY NAME" }
            }]
        }
      }
    }
    

    事实证明,这个查询不是很快,至少对于“客户账户”索引和拥有aprox的最大公司来说不是这样。1600万客户账户记录。

    我的理解是,在反向索引中,将有一个“我的公司名称”条目,其中将有1600万个文档与之关联,术语查询必须迭代所有文档。

    对查询进行分析后发现,大部分时间都花在了“next_doc”上(据我所知,这是迭代部分):

    "profile": {"shards": [   {
      "id": "[ysJiBZNTRsuha0E8LU28sA][kunden][0]",
      "searches": [      {
         "query": [         {
            "type": "BoostQuery",
            "description": "(ConstantScore(company:MY COMPANY NAME))^0.0",
            "time_in_nanos": 11295720987,
            "breakdown":             {
               "score": 2778410326,
               "build_scorer_count": 54,
               "match_count": 0,
               "create_weight": 19602,
               "next_doc": 8485047975,
               "match": 0,
               "create_weight_count": 1,
               "next_doc_count": 15728947,
               "score_count": 15728921,
               "build_scorer": 785161,
               "advance": 0,
               "advance_count": 0
            },
            "children": [            {
               "type": "TermQuery",
               "description": "company:MY COMPANY NAME",
               "time_in_nanos": 2873750226,
               "breakdown":                {
                  "score": 0,
                  "build_scorer_count": 54,
                  "match_count": 0,
                  "create_weight": 9745,
                  "next_doc": 2857426300,
                  "match": 0,
                  "create_weight_count": 1,
                  "next_doc_count": 15728947,
                  "score_count": 0,
                  "build_scorer": 585179,
                  "advance": 0,
                  "advance_count": 0
               }
            }]
         }],
    

    顺便说一下,公司字段映射为“关键字”字段。

    在这一点上,我不确定如何解决这个性能问题。

    是否有其他查询类型可以更高效地执行此操作?或者我可以用不同的方式对术语查询进行参数化,以加快查询速度?

    我还考虑将“type”和“company”的每一个组合都放在它自己的索引中,以避免“by company”这个词一起出现。

    因此,我可以通过处理适当的索引,按“类型”和“公司”进行过滤,然后只按我在这里的示例中排除的其他搜索参数进行过滤(查询的这一部分(一堆“应该”-子句)已经非常快了)

    但我也不确定这是否是一个好主意,因为这会产生很多指数(数据集中有大约60家不同的公司),其中许多公司只持有数千条或可能上万条记录。对于搜索“所有公司”的查询,我可能需要并行搜索60个索引。这似乎有可能产生一整罐不同的蠕虫。

    我很想获得一些关于如何实现这一点的意见/见解。

    提前谢谢!

    当做 马里奥

    0 回复  |  直到 7 年前