SQL プレーヤーとして、ElasticSearch に触れた後、その DSL の奇妙な記述方法に悩まされました。たとえば、bool はどのようなシナリオでフィルタする必要があるかなどです。ネストされていますが、bool はいつネストされるべきですか? クエリは必要であり、いつ実行できますか。問題のトラブルシューティングを行う場合、DSL を手動で記述することは避けられず、ES エラーが発生することがよくあります。
この問題を解決するために、ChatGPT に翻訳させてみましたが、その効果はかなり良好でした。シナリオに沿って見てみましょう。
B 側バックエンド システムのリスト ページには、通常、多くのフィルター ボックスが表示されます。プロダクト マネージャーは、「ユーザー エクスペリエンスの向上」と呼ばれるフィルター ボックスに、ID と名前によるあいまい一致の機能を組み込むことがよくあります。 SQL で書かれている場合は非常に簡単です:
select * from user where client_id = 123 anduser_id like '%张三%' or user_name like '%张三%';
MySQL に保存されている場合、client_id インデックスを追加することでフィルタリングされるデータの量を大幅に削減でき、パフォーマンスもそれほど悪くありません。
データ量が非常に大きい場合は、ES を使用します。 ChatGPT に次のように質問できます:
質問を開始します:
ES インデックス名 "user"、3 つのフィールド
次の条件でレコードをクエリしたいと思います: client_id = 123 および (user_name = 'Zhang San' または user_id = 'Zhang San')。 DSLはどうやって書けばいいのでしょうか?
返信の開始:
次の条件を満たす「user」インデックス内のレコードをクエリするには: client_id = 123 および (user_name) = 'Zhang San ' または user_id = 'Zhang San')、これを実現するには、ブール クエリと用語クエリを組み合わせて使用できます。対応する DSL クエリの例を次に示します。
GET /user/_search{"query": {"bool": {"filter": [{"term": {"client_id": 123}},{"bool": {"should": [{"term": {"user_name": "张三"}},{"term": {"user_id": "张三"}}]}}]}}}
このクエリでは、ブール クエリを使用して、指定された基準がドキュメントのフィルタリングに使用されることを確認します。
フィルター句には 2 つの条件があります。1 つは、クエリという用語を使用した、「client_id」フィールドの値が 123 であるという条件です。 2 番目の条件は、 should 句を含むネストされた bool クエリです。 should 句には 2 つの用語クエリが含まれています。1 つは「user_name」フィールドに対するもので、もう 1 つは「user_id」フィールドに対するもので、どちらも値が「Zhang San」であるかどうかをチェックします。 should 句を使用することで、いずれかの条件が一致する必要があることを示します。
この DSL クエリは、client_id が 123、ユーザー名が「Zhang San」またはユーザー ID が「Zhang San」であるドキュメント レコードを返します。
返信終了:
ChatGPT は答えを提供するだけでなく、説明も提供します。ビジネスは良いです。
上記のユーザー テーブルに基づいて、処理済みの作業指示書を表す ticket_id フィールドを追加します。 100 を超える作業指示を持つユーザーを処理します。 SQL は次のように記述できます:
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;
ChatGPT に質問する:
質問を開始する:
ES インデックス名「user」。次のフィールドが含まれます:
返信の開始:
「user_id」フィールドに従って集計し、条件を満たす「user_id」をクエリします count(ticket_id) > 100、および対応する「user_name」。これは、集計クエリで用語集計およびbucket_selectorパイプライン集計を使用して実装できます。以下は、対応する DSL クエリの例です: 在这个查询中,我们使用了 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 回复开始: 在这个查询中,我们使用了 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就开始瞎说了。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 的聚合桶}}}}}}
场景三: 聚合以后取topK
要查询处理 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}}}}}}
以上がChatGPT を使用して ElasticSearch DSL をすぐに始めましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。