firestore-batch-updater 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +22 -0
- package/README.md +22 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +28 -0
- package/dist/index.mjs +28 -0
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
- 고유값 조회 - `distinct()`로 특정 필드의 중복 없는 값 목록 조회
|
|
30
30
|
- JSON 내보내기/가져오기 - `toJSON()` / `fromJSON()`으로 문서 JSON 파일 내보내기/가져오기
|
|
31
31
|
- 그룹별 개수 조회 - `countBy()`로 특정 필드 값별 문서 수 집계
|
|
32
|
+
- 랜덤 샘플링 - `sample()`로 쿼리 결과에서 랜덤 문서 추출
|
|
32
33
|
- FieldValue 지원 - `increment()`, `arrayUnion()`, `delete()`, `serverTimestamp()` 등 사용 가능
|
|
33
34
|
- 서브컬렉션 & 컬렉션 그룹 - 서브컬렉션 쿼리 또는 동일 이름의 모든 컬렉션 쿼리
|
|
34
35
|
- Dry Run 모드 - 실제 변경 없이 작업 시뮬레이션
|
|
@@ -123,6 +124,7 @@ console.log(`${result.successCount}개 문서 업데이트 완료`);
|
|
|
123
124
|
| `transform(fn, options?)` | 커스텀 함수로 문서 변환 | `TransformResult` |
|
|
124
125
|
| `copyTo(target, options?)` | 다른 컬렉션으로 문서 복사/이동 | `CopyToResult` |
|
|
125
126
|
| `distinct(field)` | 특정 필드의 고유값 조회 | `any[]` |
|
|
127
|
+
| `sample(n)` | 매칭 문서에서 랜덤 샘플 추출 | `{ id, data }[]` |
|
|
126
128
|
| `toJSON(path, options?)` | 문서를 JSON 파일로 내보내기 | `ToJSONResult` |
|
|
127
129
|
| `fromJSON(path, options?)` | JSON 파일에서 문서 가져오기 | `FromJSONResult` |
|
|
128
130
|
| `countBy(field)` | 필드 값별 문서 수 집계 | `CountByResult` |
|
|
@@ -779,6 +781,26 @@ await updater.collection("users").toJSON("./backup.json");
|
|
|
779
781
|
await updater.collection("users_backup").fromJSON("./backup.json");
|
|
780
782
|
```
|
|
781
783
|
|
|
784
|
+
### 랜덤 샘플링
|
|
785
|
+
|
|
786
|
+
```typescript
|
|
787
|
+
// 랜덤으로 5개 문서 추출
|
|
788
|
+
const samples = await updater.collection("users").sample(5);
|
|
789
|
+
samples.forEach(doc => console.log(doc.id, doc.data.name));
|
|
790
|
+
|
|
791
|
+
// 필터된 결과에서 랜덤 샘플
|
|
792
|
+
const activeUsers = await updater
|
|
793
|
+
.collection("users")
|
|
794
|
+
.where("status", "==", "active")
|
|
795
|
+
.sample(3);
|
|
796
|
+
|
|
797
|
+
// select와 함께 사용하여 메모리 효율 극대화
|
|
798
|
+
const randomProducts = await updater
|
|
799
|
+
.collection("products")
|
|
800
|
+
.select("name", "price")
|
|
801
|
+
.sample(10);
|
|
802
|
+
```
|
|
803
|
+
|
|
782
804
|
### Dry Run 모드
|
|
783
805
|
|
|
784
806
|
```typescript
|
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ English | [한국어](./README.ko.md)
|
|
|
29
29
|
- Distinct values - Use `distinct()` to get unique field values from matching documents
|
|
30
30
|
- JSON export/import - Use `toJSON()` / `fromJSON()` to export/import documents as JSON
|
|
31
31
|
- Group counting - Use `countBy()` to count documents grouped by field value
|
|
32
|
+
- Random sampling - Use `sample()` to get random documents from query results
|
|
32
33
|
- FieldValue support - Use `increment()`, `arrayUnion()`, `delete()`, `serverTimestamp()`, etc.
|
|
33
34
|
- Subcollection & Collection Group - Query subcollections or all collections with the same name
|
|
34
35
|
- Dry run mode - Simulate operations without making changes
|
|
@@ -123,6 +124,7 @@ console.log(`Updated ${result.successCount} documents`);
|
|
|
123
124
|
| `transform(fn, options?)` | Transform docs with custom function | `TransformResult` |
|
|
124
125
|
| `copyTo(target, options?)` | Copy/move docs to another collection | `CopyToResult` |
|
|
125
126
|
| `distinct(field)` | Get unique values of a field | `any[]` |
|
|
127
|
+
| `sample(n)` | Get random sample of matching documents | `{ id, data }[]` |
|
|
126
128
|
| `toJSON(path, options?)` | Export documents to JSON file | `ToJSONResult` |
|
|
127
129
|
| `fromJSON(path, options?)` | Import documents from JSON file | `FromJSONResult` |
|
|
128
130
|
| `countBy(field)` | Count documents grouped by field value | `CountByResult` |
|
|
@@ -792,6 +794,26 @@ await updater.collection("users").toJSON("./backup.json");
|
|
|
792
794
|
await updater.collection("users_backup").fromJSON("./backup.json");
|
|
793
795
|
```
|
|
794
796
|
|
|
797
|
+
### Random Sampling
|
|
798
|
+
|
|
799
|
+
```typescript
|
|
800
|
+
// Get 5 random documents
|
|
801
|
+
const samples = await updater.collection("users").sample(5);
|
|
802
|
+
samples.forEach(doc => console.log(doc.id, doc.data.name));
|
|
803
|
+
|
|
804
|
+
// Random sample from filtered results
|
|
805
|
+
const activeUsers = await updater
|
|
806
|
+
.collection("users")
|
|
807
|
+
.where("status", "==", "active")
|
|
808
|
+
.sample(3);
|
|
809
|
+
|
|
810
|
+
// With select for memory efficiency
|
|
811
|
+
const randomProducts = await updater
|
|
812
|
+
.collection("products")
|
|
813
|
+
.select("name", "price")
|
|
814
|
+
.sample(10);
|
|
815
|
+
```
|
|
816
|
+
|
|
795
817
|
### Dry Run Mode
|
|
796
818
|
|
|
797
819
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -744,6 +744,15 @@ declare class BatchUpdater {
|
|
|
744
744
|
* @returns Array of unique values
|
|
745
745
|
*/
|
|
746
746
|
distinct(field: string): Promise<any[]>;
|
|
747
|
+
/**
|
|
748
|
+
* Get a random sample of matching documents
|
|
749
|
+
* @param n - Number of documents to sample
|
|
750
|
+
* @returns Array of randomly selected documents with { id, data }
|
|
751
|
+
*/
|
|
752
|
+
sample(n: number): Promise<{
|
|
753
|
+
id: string;
|
|
754
|
+
data: Record<string, any>;
|
|
755
|
+
}[]>;
|
|
747
756
|
/**
|
|
748
757
|
* Export matching documents to a JSON file
|
|
749
758
|
* @param filePath - Path for the output JSON file
|
package/dist/index.d.ts
CHANGED
|
@@ -744,6 +744,15 @@ declare class BatchUpdater {
|
|
|
744
744
|
* @returns Array of unique values
|
|
745
745
|
*/
|
|
746
746
|
distinct(field: string): Promise<any[]>;
|
|
747
|
+
/**
|
|
748
|
+
* Get a random sample of matching documents
|
|
749
|
+
* @param n - Number of documents to sample
|
|
750
|
+
* @returns Array of randomly selected documents with { id, data }
|
|
751
|
+
*/
|
|
752
|
+
sample(n: number): Promise<{
|
|
753
|
+
id: string;
|
|
754
|
+
data: Record<string, any>;
|
|
755
|
+
}[]>;
|
|
747
756
|
/**
|
|
748
757
|
* Export matching documents to a JSON file
|
|
749
758
|
* @param filePath - Path for the output JSON file
|
package/dist/index.js
CHANGED
|
@@ -1263,6 +1263,34 @@ var BatchUpdater = class {
|
|
|
1263
1263
|
}
|
|
1264
1264
|
return values;
|
|
1265
1265
|
}
|
|
1266
|
+
/**
|
|
1267
|
+
* Get a random sample of matching documents
|
|
1268
|
+
* @param n - Number of documents to sample
|
|
1269
|
+
* @returns Array of randomly selected documents with { id, data }
|
|
1270
|
+
*/
|
|
1271
|
+
async sample(n) {
|
|
1272
|
+
this.validateSetup();
|
|
1273
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
1274
|
+
throw new Error("Sample size must be a positive integer");
|
|
1275
|
+
}
|
|
1276
|
+
const query = this.buildQuery();
|
|
1277
|
+
const snapshot = await query.get();
|
|
1278
|
+
if (snapshot.empty) {
|
|
1279
|
+
return [];
|
|
1280
|
+
}
|
|
1281
|
+
const docs = snapshot.docs.map((doc) => ({
|
|
1282
|
+
id: doc.id,
|
|
1283
|
+
data: doc.data()
|
|
1284
|
+
}));
|
|
1285
|
+
if (docs.length <= n) {
|
|
1286
|
+
return docs;
|
|
1287
|
+
}
|
|
1288
|
+
for (let i = docs.length - 1; i > docs.length - 1 - n; i--) {
|
|
1289
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
1290
|
+
[docs[i], docs[j]] = [docs[j], docs[i]];
|
|
1291
|
+
}
|
|
1292
|
+
return docs.slice(docs.length - n);
|
|
1293
|
+
}
|
|
1266
1294
|
/**
|
|
1267
1295
|
* Export matching documents to a JSON file
|
|
1268
1296
|
* @param filePath - Path for the output JSON file
|
package/dist/index.mjs
CHANGED
|
@@ -1218,6 +1218,34 @@ var BatchUpdater = class {
|
|
|
1218
1218
|
}
|
|
1219
1219
|
return values;
|
|
1220
1220
|
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Get a random sample of matching documents
|
|
1223
|
+
* @param n - Number of documents to sample
|
|
1224
|
+
* @returns Array of randomly selected documents with { id, data }
|
|
1225
|
+
*/
|
|
1226
|
+
async sample(n) {
|
|
1227
|
+
this.validateSetup();
|
|
1228
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
1229
|
+
throw new Error("Sample size must be a positive integer");
|
|
1230
|
+
}
|
|
1231
|
+
const query = this.buildQuery();
|
|
1232
|
+
const snapshot = await query.get();
|
|
1233
|
+
if (snapshot.empty) {
|
|
1234
|
+
return [];
|
|
1235
|
+
}
|
|
1236
|
+
const docs = snapshot.docs.map((doc) => ({
|
|
1237
|
+
id: doc.id,
|
|
1238
|
+
data: doc.data()
|
|
1239
|
+
}));
|
|
1240
|
+
if (docs.length <= n) {
|
|
1241
|
+
return docs;
|
|
1242
|
+
}
|
|
1243
|
+
for (let i = docs.length - 1; i > docs.length - 1 - n; i--) {
|
|
1244
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
1245
|
+
[docs[i], docs[j]] = [docs[j], docs[i]];
|
|
1246
|
+
}
|
|
1247
|
+
return docs.slice(docs.length - n);
|
|
1248
|
+
}
|
|
1221
1249
|
/**
|
|
1222
1250
|
* Export matching documents to a JSON file
|
|
1223
1251
|
* @param filePath - Path for the output JSON file
|