Sebagai pemain SQL, selepas berhubung dengan ElasticSearch, saya terganggu dengan cara pelik menulis dslnya, seperti bool harus menapis dalam senario yang sepatutnya bersarang, dan bilakah bool perlu bersarang? Pertanyaan diperlukan dan bilakah ia boleh dilakukan. Apabila menyelesaikan masalah, ia tidak dapat dielakkan untuk menulis dsl dengan tangan, dan sering menerima ralat ES.
Untuk menyelesaikan masalah ini, saya cuba membenarkan ChatGPT menterjemah untuk saya, dan kesannya cukup bagus. Mari kita lihat mengikut senario.
Dalam halaman senarai sistem hujung belakang sebelah B, biasanya kita boleh melihat banyak kotak penapis. Pengurus produk sering meletakkan fungsi padanan kabur mengikut ID dan Nama ke dalam kotak penapis yang dipanggil "pengalaman pengguna yang lebih baik". Jika ditulis dalam SQL, ia sangat mudah:
select * from user where client_id = 123 anduser_id like '%张三%' or user_name like '%张三%';
Jika disimpan dalam MySQL, menambah indeks client_id boleh mengurangkan jumlah data yang ditapis dan prestasinya tidak akan terlalu buruk.
Jika jumlah data sangat besar, maka gunakan ES. Kita boleh bertanya kepada ChatGPT seperti ini:
Soalan bermula:
Nama indeks ES "pengguna", mempunyai tiga medan
Saya ingin menanyakan rekod dengan syarat berikut: client_id = 123 dan (user_name = 'Zhang San' atau user_id = 'Zhang San'). Bagaimana saya harus menulis dsl?
Mulakan balasan:
Untuk menanyakan rekod yang memenuhi syarat berikut dalam indeks "pengguna": client_id = 123 dan (nama_pengguna = 'Zhang San ' atau user_id = 'Zhang San'), anda boleh menggunakan pertanyaan bool digabungkan dengan pertanyaan istilah untuk mencapai ini. Berikut ialah contoh pertanyaan DSL yang sepadan:
GET /user/_search{"query": {"bool": {"filter": [{"term": {"client_id": 123}},{"bool": {"should": [{"term": {"user_name": "张三"}},{"term": {"user_id": "张三"}}]}}]}}}
Dalam pertanyaan ini, kami menggunakan pertanyaan bool untuk memastikan kriteria yang ditentukan digunakan untuk menapis dokumen.
Dalam klausa penapis, kita mempunyai dua syarat: satu adalah untuk syarat bahawa nilai medan "client_id" ialah 123, menggunakan pertanyaan istilah. Syarat kedua ialah pertanyaan bool bersarang yang mengandungi klausa should. Klausa harus mengandungi dua pertanyaan istilah: satu untuk medan "nama_pengguna" dan satu lagi untuk medan "id_pengguna", yang kedua-duanya menyemak sama ada nilainya ialah "Zhang San". Dengan menggunakan klausa harus, kami menunjukkan bahawa mana-mana satu syarat mesti sepadan.
Pertanyaan DSL ini akan mengembalikan rekod dokumen yang client_idnya ialah 123 dan nama pengguna ialah "Zhang San" atau ID pengguna ialah "Zhang San".
Tamat balasan:
ChatGPT bukan sahaja memberi jawapan, malah memberi penjelasan Mari kita buat sedikit pengubahsuaian pada indeks dalam perniagaan yang baik.
Berdasarkan jadual pengguna di atas, kami menambah medan ticket_id untuk mewakili pesanan kerja yang diproses, kami ingin menyemak Memproses pengguna dengan lebih daripada 100 pesanan kerja. SQL boleh ditulis seperti ini:
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;
Tanya soalan kepada ChatGPT:
Soalan mula:
Nama indeks ES "pengguna", termasuk medan berikut:
Penggabungan mengikut user_id, query count(ticket_id) > id_pengguna dan id_pengguna Nama_pengguna yang sepadan
Permulaan balasan:
Untuk mengagregat mengikut medan "id_pengguna" dan tanya "id_pengguna" yang memenuhi bilangan syarat(id_tiket) > ; 100, dan "nama_pengguna" yang sepadan, yang boleh dilaksanakan menggunakan istilah agregasi dan bucket_selector agregasi saluran paip dalam pertanyaan agregat. Berikut ialah contoh pertanyaan DSL yang sepadan:
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就开始瞎说了。
Atas ialah kandungan terperinci Mulakan dengan pantas dengan ElasticSearch dsl dengan ChatGPT. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!