我最近第一次开始使用Elastic Search,并且正在寻找一些见解/帮助。我有一个术语查询的问题,该查询的性能不是很好,使我相信我对索引进行“分区”的方法可能不是最好的。我希望有人能对此有所了解。
我需要进入Elastic Search的数据集包括大约。 60-7000万条记录。记录基本上是个人+地址+元数据记录,并且有两种明显的方式将它们分区/分割为多个索引。我现在做的方式是创建4个索引。这4个索引与数据集中包含的4种不同“记录类型”相关联。可以将这4种类型视为“客户帐户”,“潜在客户”,“债务人”和“黑名单人员/地址”。这4个索引中的每个记录都与一家公司相关联,我希望能够(除其他外)按“类型”和“公司”进行搜索。
“按类型”很容易,我只是解决与类型相关联的索引。对于“按公司”部分,我开始使用像这样的术语查询(这是一个布尔查询,因为它通常包括其他搜索参数,出于简洁/清晰起见,在此不包括):
{
"query": {
"bool": {
"filter": [{
"term": { "company": "MY COMPANY NAME" }
}]
}
}
}
事实证明,此查询不是非常快,至少不是针对“客户帐户”索引以及具有代理的最大公司。 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
}
}]
}],
顺便说一句,公司字段被映射为“关键字”字段。
目前我不确定如何解决此性能问题。
也许还有另一种查询类型可以更有效地做到这一点?还是我可以不同地参数化术语查询以使其更快?
我还考虑过将“类型”和“公司”的每种组合放入其自己的索引中,以避免将“按公司”查询一词统统避免。
例如,我将拥有一个名为“ prospects_COMPANY_A”的索引,另一个名为“ prospects_COMPANY_B”的索引,另一个名为“ debtors_COMPANY_A”的索引,依此类推。
因此,我可以通过查找适当的索引来按“类型”和“公司”进行过滤,然后仅按我在此处的示例中排除的其他搜索参数进行过滤(查询的那一部分(一堆“应该” -子句)已经非常快了
但我不确定这是否是一个好主意,因为这会导致很多索引(数据集中有大约60个不同的公司),其中许多公司只持有几千或也许有上万条记录。对于搜索“所有公司”的查询,我可能必须并行搜索60个索引。似乎有可能带来完全不同的蠕虫病毒。
我希望获得一些有关如何实现此目标的意见。
谢谢!
致谢 马里奥