FJCT_ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

スクリプトで検索したデータを大量削除する【Ruby】

f:id:mbaasblog:20190620114158p:plain:w300

スクリプト機能を使ってクラス内のオブジェクトを一度に大量削除する方法を紹介します。

はじめに

mBaaS開発チームでOJT中、2019年度新入社員の上村です。
mBaaSのAPIにあるオブジェクト削除 では、オブジェクトを1件ずつしか削除出来ません。また、REST APIでは1000件までの情報を一度に取得できますが、もっと大量のオブジェクトを一度に削除したいときってありますよね。

そこで、スクリプト機能を使ってクラス内のオブジェクトを一度に大量削除する方法を紹介します。

削除するサンプルオブジェクトの準備

後述のサンプルスクリプトで削除するのは、

  • クラス名: Item
  • レコード:
    • field1: 20 (数値)
    • field2: hoge (文字列)

が存在するオブジェクトです。これらの検索条件は後にQueryで指定します。

f:id:mbaasblog:20190620114835p:plain

スクリプト作成

まずスクリプトを作成します。今回はRubyで作成していきます。

APPLICATION_KEYCLIENT_KEY はご自身のアプリケーションキーとクライアントキーに差し替えてください。

require "rack"
require "ncmb"
NCMB.initialize(
                application_key: "APPLICATION_KEY",
                client_key: "CLIENT_KEY" 
                )
def call(env)
    req = Rack::Request.new(env)
    # クエリで読み込むパラメータを宣言
    # クエリは文字列で読み込まれるため、数値(int)を入れたいときは末尾に .to_i を入れる
    class_name = req.params["class_name"]
    field_name1 = req.params["field_name1"]
    field_name2 = req.params["field_name2"]
    value1 = req.params["value1"].to_i
    value2 = req.params["value2"]
    limit_num = 1000
    
    begin
        skip_num=0
        items = []
        loop do
            # クラス内の情報を検索して取得
            item = NCMB::DataStore.new(class_name).skip(limit_num * skip_num).limit(limit_num)
              items.push(item.where(field_name1, value1).where(field_name2, value2).all)
            if item.all.count < limit_num
                break
            end
            skip_num+=1
        end
        
        # 取得したオブジェクトを削除
        for delete_num in 0..skip_num
            items[delete_num].each { |i| i.delete }
        end
    
        # 成功
        return [
        200,
        {"Content-Type" => "application/json"},
        [{"result" => "DELETE data successfully!"}.to_json]
        ]
        rescue => e
        # 失敗
        return [
        500,
        {"Content-Type" => "application/json"},
        [{"error" => e.message}.to_json]
        ]
    end
end

オペレータ

また、whereキーのクエリでは完全一致だけでなく、 オペレータを用いることで複雑な検索ができます。

今回のコードでは以下のような検索をしていますが、

item.where("field1", 20).where("field2", "hoge").all

これにオペレータを使い、field1が 10 以上でfield2に ho が含まれるオブジェクト情報を検索するコードに書き換えると以下のようになります。

item.where("field1","$gt":10).where("field2","$regex":"ho").all

ぜひカスタマイズして使ってみてくださいね。

スクリプトのアップロード

上記スクリプトをmBaaSコンソールの「スクリプト」からアップロードします。メソッドはDELETEです。

f:id:mbaasblog:20190620115022p:plain

スクリプトの実行

アップロードしたスクリプトを選択し、実行タブからクエリパラメータを指定します。 今回はQueryに以下のように入力します。

class_name=Item&field_name1=field1&value1=20&field_name2=field2&value2=hoge

f:id:mbaasblog:20190620115142p:plain

実行すると、検索で絞り込んだオブジェクトが削除されていることが確認できるはずです。

f:id:mbaasblog:20190620115156p:plain

タイムアウトエラーが発生してしまう場合は、検索条件に当てはまるデータがすべて削除されるまでスクリプトを複数回実行していただければと思います。

まとめ

今回はRubyスクリプトを使ったデータ大量削除の方法を紹介しました。 Node.jsで大量にデータを削除する場合はこちらを参考にご覧ください。

f:id:mbaasblog:20190621094339j:plain

上村 智子

富士通クラウドテクノロジーズ株式会社に2019年度新卒入社。OJTでニフクラ mobile backend 開発チームに所属。