大量のデータを保存し、そのデータに重複がないか確認してから保存する機能があります。重複するチェックごとにデータベースをクエリすると、スクリプトが最大実行時間を超えるため、データベース全体をクエリしてから、そのクエリに対してチェックします。問題は、重複チェックを実行すると、クエリサイズが4番目のパスまでにゼロに減少し、効果がなくなることです。保存関数と重複チェックのコードは次のとおりです。
function ssToScriptDb_1() {
var spreadsheet = SpreadsheetApp.openById('0Ah1c1zmu5vU_dEZJYVMzVnF6Y211cmJGdjZBUGFLQWc'); // **** create a function to prompt for the ID
var sheet = spreadsheet.getActiveSheet();
var columns = spreadsheet.getLastColumn();
var data = sheet.getDataRange().getValues();
var keys = data[0];
var db = ScriptDb.getMyDb();
var allDb = db.query({});
var items = [];
for (var row = 1; row < data.length; row++) {
var rowData = data[row];
var item = {};
for (var column = 0; column < keys.length; column++) {
item[keys[column]] = rowData[column]; // ???? could I use this notation in place of the double for loops in timeClock?
}
item.visitDate = Utilities.formatDate(item.visitDate, "MST", "M/d/yyyy");
// check to see if the item is already in the db
if (dupCheck(db, allDb, item)) {
items.push(item);
}
if (row % 1000 == 0) {
Logger.log("row " + row + " completed at " + new Date() +"\n");
}
}
var itemsLen = items.length;
Logger.log('DB save start time ' + new Date() + '\n');
var results = db.saveBatch(items, false);
Logger.log('DB save end time ' + new Date() + '\n');
}
function dupCheck(db, query, item) {
var count = 0;
var querySize = query.getSize();
var query2Size = db.query({}).getSize();
while (query.hasNext()) {
var ob = query.next();
if (ob.ID == item.ID && ob.email == item.email && ob.visitDate == item.visitDate) {
return false;
}
count++;
}
return true;
}
デバッグの最初のパススルーはdupCheck()
次のようになります。
querySize
入力する前に実行されるクエリdupCheck()
であり、query2Sizeは内部で実行されるクエリと同じであることに注意してdupCheck()
ください。
これが2回目のパススルーdupCheck()
です:
これが4番目のパスです。
querySize
もう一度vsに注意してquery2Size
ください。
元のクエリが減少する原因はわかりませんが、各アイテムのクエリを呼び出すことはできません。これを引き起こしている原因や、より良い解決策があるかどうかはわかりません。