Als SQL-Spieler war ich, nachdem ich mit ElasticSearch in Kontakt gekommen war, über die seltsamen Schreibmethoden seiner DSL beunruhigt, z. B. in welchen Szenarien ein Bool-Filter verschachtelt werden sollte, wann eine Bool-Abfrage erforderlich ist und wann dies möglich ist es beseitigt werden. Bei der Fehlerbehebung ist es unvermeidlich, DSL manuell zu schreiben, und es treten häufig ES-Fehler auf.
Um dieses Problem zu lösen, habe ich versucht, ChatGPT für mich übersetzen zu lassen, und der Effekt war ziemlich gut. Schauen wir es uns je nach Szenario an.
Auf der Listenseite des B-seitigen Backend-Systems sehen wir normalerweise viele Filterfelder. Produktmanager ordnen die Funktion des Fuzzy-Matchings nach ID und Name häufig einem Filterfeld namens „Bessere Benutzererfahrung“ zu. Wenn es in SQL geschrieben ist, ist es sehr einfach:
select * from user where client_id = 123 anduser_id like '%张三%' or user_name like '%张三%';
Wenn es in MySQL gespeichert ist, kann das Hinzufügen des client_id-Index die Menge der gefilterten Daten erheblich reduzieren, und die Leistung wird nicht allzu schlecht sein.
Wenn die Datenmenge sehr groß ist, dann verwenden Sie ES. Wir können ChatGPT folgendermaßen fragen:
Beginnen Sie die Frage:
ES-Indexname „Benutzer“, es gibt drei Felder
Ich möchte Datensätze mit den folgenden Bedingungen abfragen: client_id = 123 und (user_name = 'Zhang San' oder user_id = 'Zhang San'). Wie soll ich DSL schreiben?
Beginn der Antwort:
Um die Datensätze im „Benutzer“-Index abzufragen, die die folgenden Bedingungen erfüllen: client_id = 123 und (user_name = ‚Zhang San‘ oder user_id = ‚Zhang San‘), können Sie Um dies zu erreichen, verwenden Sie eine Bool-Abfrage in Kombination mit einer Begriffsabfrage. Hier ist ein Beispiel für die entsprechende DSL-Abfrage:
GET /user/_search{"query": {"bool": {"filter": [{"term": {"client_id": 123}},{"bool": {"should": [{"term": {"user_name": "张三"}},{"term": {"user_id": "张三"}}]}}]}}}
In dieser Abfrage verwenden wir eine Bool-Abfrage, um sicherzustellen, dass die angegebenen Kriterien zum Filtern der Dokumente verwendet werden.
In der Filterklausel haben wir zwei Bedingungen: Eine gilt für die Bedingung, dass der Wert des Felds „client_id“ 123 ist, unter Verwendung des Begriffs „Abfrage“. Die zweite Bedingung ist eine verschachtelte Bool-Abfrage, die eine Should-Klausel enthält. Die sollte-Klausel enthält zwei Begriffsabfragen: eine für das Feld „user_name“ und die andere für das Feld „user_id“, die beide prüfen, ob der Wert „Zhang San“ ist. Durch die Verwendung der Should-Klausel geben wir an, dass eine der Bedingungen zutreffen muss.
Diese DSL-Abfrage gibt Dokumentdatensätze zurück, deren client_id 123 ist und deren Benutzername „Zhang San“ oder die Benutzer-ID „Zhang San“ ist.
Ende der Antwort:
ChatGPT hat nicht nur die Antwort gegeben, sondern auch eine Erklärung abgegeben. Wir können einfach einige Änderungen am Index im Unternehmen vornehmen.
Basierend auf der Benutzertabelle oben fügen wir ein Ticket_ID-Feld hinzu, um die verarbeiteten Arbeitsaufträge darzustellen. Wir möchten die Benutzer herausfinden, die mehr als 100 Arbeitsaufträge bearbeitet haben. SQL kann wie folgt geschrieben werden:
select user_id, max(user_name) as user_name,count(ticket_id) as ticket_cnt from user where client_id = 123having count(ticket_id) > 100;
Ask ChatGPT:
Beginnen Sie mit der Frage:
ES-Indexname „Benutzer“, der die folgenden Felder enthält:
Aggregation nach user_id, Abfrage der user_id von count(ticket_id) > 100 und des user_name, der der user_id entspricht. Die Antwort beginnt: „user_id“-Feld Aggregation und Abfrage von „user_id“, die die Bedingung count(ticket_id) > erfüllt, und des entsprechenden „user_name“ können mithilfe der Begriffe Aggregation und Bucket_Selector-Pipeline-Aggregation in der Aggregationsabfrage implementiert werden. Hier ist das entsprechende DSL-Abfragebeispiel:
GET /user/_search{"size": 0,"aggs": {"users": {"terms": {"field": "user_id","size": 10,"min_doc_count": 101// 设置最小文档数,只返回 count(ticket_id) > 100 的聚合结果},"aggs": {"user_name": {"terms": {"field": "user_name","size": 1}},"ticket_count": {"value_count": {"field": "ticket_id"}},"bucket_filter": {"bucket_selector": {"buckets_path": {"count": "ticket_count"},"script": "params.count > 100"// 仅保留 count(ticket_id) > 100 的聚合桶}}}}}}
在这个查询中,我们使用了 terms 聚合对 "user_id" 字段进行分组,并在聚合结果中嵌套了 user_name 字段的 terms 聚合和 ticket_id 字段的 value_count 聚合。
在 terms 聚合中,我们设置了 min_doc_count 参数为 101,以仅返回满足 count(ticket_id) > 100 的聚合桶。这样可以过滤掉不满足条件的聚合结果。
最终,我们使用 bucket_selector 管道聚合来进行桶过滤,仅保留满足条件 params.count > 100 的聚合桶。这样,最终的聚合结果中将只包含满足条件的 "user_id" 和对应的 "user_name"。
请注意,根据您的具体需求,您可能需要根据实际情况调整聚合查询中的参数和设置,如设置合适的 size 值来控制返回的聚合桶数量等。
回复结束。
向ChatGPT提问:
提问开始:
ES index 名字 "user",包含以下字段:
我要查询处理ticket数量top10 的 user_id 以及对应的user_name
回复开始:
要查询处理 ticket 数量排名前 10 的 "user_id",以及对应的 "user_name",可以使用 terms 聚合和 top_hits 子聚合来实现。以下是相应的 DSL 查询示例:
GET /user/_search{"size": 0,"aggs": {"top_users": {"terms": {"field": "user_id","size": 10,"order": {"ticket_count": "desc"}},"aggs": {"user_name": {"terms": {"field": "user_name","size": 1}},"ticket_count": {"value_count": {"field": "ticket_id"}},"top_user_hits": {"top_hits": {"size": 1}}}}}}
在这个查询中,我们使用了 terms 聚合对 "user_id" 字段进行分组,并按照 "ticket_count" 字段的降序对分组结果进行排序。
在 terms 聚合中,我们设置了 size 参数为 10,以仅返回前 10 个处理 ticket 数量最多的 "user_id"。
在每个聚合桶中,我们还嵌套了 user_name 字段的 terms 聚合和 ticket_id 字段的 value_count 聚合,分别用于获取对应的 "user_name" 和计算 ticket 数量。
此外,我们使用了 top_hits 子聚合来获取每个聚合桶中的匹配文档的详细信息。在这里,我们设置了 size 参数为 1,以仅获取每个聚合桶中的一条文档信息。
最终,聚合查询的结果将包含处理 ticket 数量排名前 10 的 "user_id",对应的 "user_name",以及每个用户最新的一条文档信息。
请注意,根据实际情况,您可能需要根据具体需求调整聚合查询中的参数和设置,如设置合适的 size 值来控制返回的聚合桶数量,以及添加其他的聚合或过滤条件等。
回复结束。
本着快速出活/快速解决问题的心态,ChatGPT确实提升了工作效率。不过在解决需求之后,还是要补补课,了解下ElasticSearch的用法和工作机制。因为ChatGPT是语言模型,一旦逻辑复杂起来,ChatGPT就开始瞎说了。
Das obige ist der detaillierte Inhalt vonStarten Sie schnell mit ElasticSearch dsl mit ChatGPT. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!