firestore-batch-updater 1.17.0 → 1.19.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 +50 -0
- package/README.md +50 -0
- package/dist/index.d.mts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +44 -0
- package/dist/index.mjs +44 -0
- package/package.json +1 -1
package/README.ko.md
CHANGED
|
@@ -24,12 +24,14 @@
|
|
|
24
24
|
- 통합 통계 - `fieldStats()`로 sum/avg/min/max/count 한 번에 조회
|
|
25
25
|
- 커서 페이지네이션 - `paginate()`로 메모리 효율적인 페이지 단위 조회
|
|
26
26
|
- ID 직접 조회 - `getOne()`으로 문서 ID로 빠른 조회
|
|
27
|
+
- 문서 ID 존재 확인 - `has(id)`로 데이터 읽기 없이 특정 문서 ID 존재 여부 확인
|
|
27
28
|
- 벌크 작업 - `bulkCreate()`, `bulkUpdate()`, `bulkDelete()`로 여러 문서에 각기 다른 데이터로 효율적 처리
|
|
28
29
|
- 문서 변환 - `transform()`으로 각 문서에 커스텀 로직 적용 (가격 인상, 데이터 마이그레이션 등)
|
|
29
30
|
- 복사 & 이동 - `copyTo()`로 컬렉션 간 문서 복사/이동 (데이터 변환 옵션 포함)
|
|
30
31
|
- 고유값 조회 - `distinct()`로 특정 필드의 중복 없는 값 목록 조회
|
|
31
32
|
- JSON 내보내기/가져오기 - `toJSON()` / `fromJSON()`으로 문서 JSON 파일 내보내기/가져오기
|
|
32
33
|
- 그룹별 개수 조회 - `countBy()`로 특정 필드 값별 문서 수 집계
|
|
34
|
+
- 그룹별 문서 조회 - `groupBy()`로 필드 값별로 문서 그룹핑
|
|
33
35
|
- 랜덤 샘플링 - `sample()`로 쿼리 결과에서 랜덤 문서 추출
|
|
34
36
|
- 필드 값 추출 - `pluck()`로 특정 필드 값만 간단하게 배열로 추출
|
|
35
37
|
- 문서 ID 추출 - `pluckIds()`로 매칭 문서의 ID만 배열로 추출
|
|
@@ -108,6 +110,7 @@ console.log(`${result.successCount}개 문서 업데이트 완료`);
|
|
|
108
110
|
| `isEmpty()` | 매칭되는 문서가 없는지 확인 | `boolean` |
|
|
109
111
|
| `findOne()` | 첫 번째 매칭 문서 조회 | `{ id, data } \| null` |
|
|
110
112
|
| `getOne(id)` | ID로 문서 직접 조회 | `{ id, data } \| null` |
|
|
113
|
+
| `has(id)` | 문서 ID 존재 여부 확인 | `boolean` |
|
|
111
114
|
| `getAll()` | 모든 매칭 문서 조회 | `{ id, data }[]` |
|
|
112
115
|
| `preview(data)` | 업데이트 전 미리보기 | `PreviewResult` |
|
|
113
116
|
| `update(data, options?)` | 매칭되는 문서 업데이트 | `UpdateResult` |
|
|
@@ -136,6 +139,7 @@ console.log(`${result.successCount}개 문서 업데이트 완료`);
|
|
|
136
139
|
| `toJSON(path, options?)` | 문서를 JSON 파일로 내보내기 | `ToJSONResult` |
|
|
137
140
|
| `fromJSON(path, options?)` | JSON 파일에서 문서 가져오기 | `FromJSONResult` |
|
|
138
141
|
| `countBy(field)` | 필드 값별 문서 수 집계 | `CountByResult` |
|
|
142
|
+
| `groupBy(field)` | 필드 값별 문서 그룹핑 | `GroupByResult` |
|
|
139
143
|
| `getFields(field)` | 특정 필드 값 조회 | `FieldValueResult[]` |
|
|
140
144
|
|
|
141
145
|
### 옵션
|
|
@@ -194,6 +198,7 @@ console.log(`${result.successCount}개 문서 업데이트 완료`);
|
|
|
194
198
|
| `ToJSONResult` | `filePath`, `documentCount` |
|
|
195
199
|
| `FromJSONResult` | `successCount`, `failureCount`, `totalCount`, `createdIds[]`, `failedDocIds?`, `logFilePath?` |
|
|
196
200
|
| `CountByResult` | `{ [value]: number }` |
|
|
201
|
+
| `GroupByResult` | `{ [value]: { id, data }[] }` |
|
|
197
202
|
| `FieldValueResult` | `id`, `value` |
|
|
198
203
|
|
|
199
204
|
## 사용 예시
|
|
@@ -643,6 +648,24 @@ const order = await updater
|
|
|
643
648
|
.getOne("order-456");
|
|
644
649
|
```
|
|
645
650
|
|
|
651
|
+
### 문서 ID 존재 확인
|
|
652
|
+
|
|
653
|
+
```typescript
|
|
654
|
+
// 특정 문서 ID가 존재하는지 확인 (데이터 읽기 없이 효율적)
|
|
655
|
+
const exists = await updater.collection("users").has("user-123");
|
|
656
|
+
|
|
657
|
+
if (exists) {
|
|
658
|
+
console.log("사용자가 존재합니다!");
|
|
659
|
+
} else {
|
|
660
|
+
console.log("사용자를 찾을 수 없음");
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// 가드 절에 유용
|
|
664
|
+
if (!(await updater.collection("users").has(userId))) {
|
|
665
|
+
throw new Error("사용자를 찾을 수 없습니다");
|
|
666
|
+
}
|
|
667
|
+
```
|
|
668
|
+
|
|
646
669
|
### 벌크 업데이트
|
|
647
670
|
|
|
648
671
|
```typescript
|
|
@@ -812,6 +835,33 @@ const countryCounts = await updater.collection("users").countBy("address.country
|
|
|
812
835
|
console.log(countryCounts); // { US: 80, KR: 45, JP: 25 }
|
|
813
836
|
```
|
|
814
837
|
|
|
838
|
+
### 필드 값별 문서 그룹핑
|
|
839
|
+
|
|
840
|
+
```typescript
|
|
841
|
+
// 필드 값별로 문서를 그룹핑 (전체 문서 데이터 포함)
|
|
842
|
+
const usersByRole = await updater.collection("users").groupBy("role");
|
|
843
|
+
|
|
844
|
+
console.log(`관리자: ${usersByRole.admin.length}명`);
|
|
845
|
+
usersByRole.admin.forEach(user => {
|
|
846
|
+
console.log(`- ${user.id}: ${user.data.name}`);
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
// where 필터와 함께 사용
|
|
850
|
+
const activeProducts = await updater
|
|
851
|
+
.collection("products")
|
|
852
|
+
.where("status", "==", "active")
|
|
853
|
+
.groupBy("category");
|
|
854
|
+
|
|
855
|
+
for (const [category, products] of Object.entries(activeProducts)) {
|
|
856
|
+
console.log(`${category}: ${products.length}개`);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// 중첩 필드 지원
|
|
860
|
+
const usersByCountry = await updater
|
|
861
|
+
.collection("users")
|
|
862
|
+
.groupBy("address.country");
|
|
863
|
+
```
|
|
864
|
+
|
|
815
865
|
### JSON 가져오기
|
|
816
866
|
|
|
817
867
|
```typescript
|
package/README.md
CHANGED
|
@@ -24,12 +24,14 @@ English | [한국어](./README.ko.md)
|
|
|
24
24
|
- Combined stats - Use `fieldStats()` to get sum/avg/min/max/count in one call
|
|
25
25
|
- Cursor pagination - Use `paginate()` for memory-efficient page-by-page iteration
|
|
26
26
|
- Direct ID lookup - Use `getOne()` for fast document retrieval by ID
|
|
27
|
+
- Document ID check - Use `has(id)` to check if a specific document ID exists without reading data
|
|
27
28
|
- Bulk operations - Use `bulkCreate()`, `bulkUpdate()`, `bulkDelete()` for efficient multi-document operations with different data each
|
|
28
29
|
- Transform - Use `transform()` to apply custom logic to each document (e.g., price increase, data migration)
|
|
29
30
|
- Copy & Move - Use `copyTo()` to copy/move documents between collections with optional data transformation
|
|
30
31
|
- Distinct values - Use `distinct()` to get unique field values from matching documents
|
|
31
32
|
- JSON export/import - Use `toJSON()` / `fromJSON()` to export/import documents as JSON
|
|
32
33
|
- Group counting - Use `countBy()` to count documents grouped by field value
|
|
34
|
+
- Group documents - Use `groupBy()` to group matching documents by a field value
|
|
33
35
|
- Random sampling - Use `sample()` to get random documents from query results
|
|
34
36
|
- Field value extraction - Use `pluck()` to get a simple array of field values
|
|
35
37
|
- Document ID extraction - Use `pluckIds()` to get an array of matching document IDs
|
|
@@ -108,6 +110,7 @@ console.log(`Updated ${result.successCount} documents`);
|
|
|
108
110
|
| `isEmpty()` | Check if no matching documents exist | `boolean` |
|
|
109
111
|
| `findOne()` | Find first matching document | `{ id, data } \| null` |
|
|
110
112
|
| `getOne(id)` | Get document by ID directly | `{ id, data } \| null` |
|
|
113
|
+
| `has(id)` | Check if document ID exists | `boolean` |
|
|
111
114
|
| `getAll()` | Get all matching documents | `{ id, data }[]` |
|
|
112
115
|
| `preview(data)` | Preview changes before update | `PreviewResult` |
|
|
113
116
|
| `update(data, options?)` | Update matching documents | `UpdateResult` |
|
|
@@ -136,6 +139,7 @@ console.log(`Updated ${result.successCount} documents`);
|
|
|
136
139
|
| `toJSON(path, options?)` | Export documents to JSON file | `ToJSONResult` |
|
|
137
140
|
| `fromJSON(path, options?)` | Import documents from JSON file | `FromJSONResult` |
|
|
138
141
|
| `countBy(field)` | Count documents grouped by field value | `CountByResult` |
|
|
142
|
+
| `groupBy(field)` | Group documents by field value | `GroupByResult` |
|
|
139
143
|
| `getFields(field)` | Get specific field values | `FieldValueResult[]` |
|
|
140
144
|
|
|
141
145
|
### Options
|
|
@@ -194,6 +198,7 @@ All write operations support an optional `options` parameter:
|
|
|
194
198
|
| `ToJSONResult` | `filePath`, `documentCount` |
|
|
195
199
|
| `FromJSONResult` | `successCount`, `failureCount`, `totalCount`, `createdIds[]`, `failedDocIds?`, `logFilePath?` |
|
|
196
200
|
| `CountByResult` | `{ [value]: number }` |
|
|
201
|
+
| `GroupByResult` | `{ [value]: { id, data }[] }` |
|
|
197
202
|
| `FieldValueResult` | `id`, `value` |
|
|
198
203
|
|
|
199
204
|
## Usage Examples
|
|
@@ -662,6 +667,24 @@ const profile = await updater
|
|
|
662
667
|
.getOne("user-123");
|
|
663
668
|
```
|
|
664
669
|
|
|
670
|
+
### Check Document Exists by ID
|
|
671
|
+
|
|
672
|
+
```typescript
|
|
673
|
+
// Check if a specific document ID exists (without reading data)
|
|
674
|
+
const exists = await updater.collection("users").has("user-123");
|
|
675
|
+
|
|
676
|
+
if (exists) {
|
|
677
|
+
console.log("User exists!");
|
|
678
|
+
} else {
|
|
679
|
+
console.log("User not found");
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Useful for guard clauses before operations
|
|
683
|
+
if (!(await updater.collection("users").has(userId))) {
|
|
684
|
+
throw new Error("User not found");
|
|
685
|
+
}
|
|
686
|
+
```
|
|
687
|
+
|
|
665
688
|
### Bulk Update with Different Data
|
|
666
689
|
|
|
667
690
|
```typescript
|
|
@@ -825,6 +848,33 @@ const countryCounts = await updater.collection("users").countBy("address.country
|
|
|
825
848
|
console.log(countryCounts); // { US: 80, KR: 45, JP: 25 }
|
|
826
849
|
```
|
|
827
850
|
|
|
851
|
+
### Group Documents by Field Value
|
|
852
|
+
|
|
853
|
+
```typescript
|
|
854
|
+
// Group documents by a field value (with full document data)
|
|
855
|
+
const usersByRole = await updater.collection("users").groupBy("role");
|
|
856
|
+
|
|
857
|
+
console.log(`Admins: ${usersByRole.admin.length}`);
|
|
858
|
+
usersByRole.admin.forEach(user => {
|
|
859
|
+
console.log(`- ${user.id}: ${user.data.name}`);
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
// With where filter
|
|
863
|
+
const activeProducts = await updater
|
|
864
|
+
.collection("products")
|
|
865
|
+
.where("status", "==", "active")
|
|
866
|
+
.groupBy("category");
|
|
867
|
+
|
|
868
|
+
for (const [category, products] of Object.entries(activeProducts)) {
|
|
869
|
+
console.log(`${category}: ${products.length} products`);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// Nested field support
|
|
873
|
+
const usersByCountry = await updater
|
|
874
|
+
.collection("users")
|
|
875
|
+
.groupBy("address.country");
|
|
876
|
+
```
|
|
877
|
+
|
|
828
878
|
### Import from JSON
|
|
829
879
|
|
|
830
880
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -472,6 +472,16 @@ interface FieldStatsResult {
|
|
|
472
472
|
interface CountByResult {
|
|
473
473
|
[value: string]: number;
|
|
474
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* Result of groupBy operation
|
|
477
|
+
* Field value → array of matching documents
|
|
478
|
+
*/
|
|
479
|
+
interface GroupByResult {
|
|
480
|
+
[value: string]: {
|
|
481
|
+
id: string;
|
|
482
|
+
data: Record<string, any>;
|
|
483
|
+
}[];
|
|
484
|
+
}
|
|
475
485
|
/**
|
|
476
486
|
* Options for fromJSON operation
|
|
477
487
|
*/
|
|
@@ -619,6 +629,12 @@ declare class BatchUpdater {
|
|
|
619
629
|
id: string;
|
|
620
630
|
data: Record<string, any>;
|
|
621
631
|
} | null>;
|
|
632
|
+
/**
|
|
633
|
+
* Check if a document with the given ID exists in the collection
|
|
634
|
+
* @param id - Document ID to check
|
|
635
|
+
* @returns true if the document exists, false otherwise
|
|
636
|
+
*/
|
|
637
|
+
has(id: string): Promise<boolean>;
|
|
622
638
|
/**
|
|
623
639
|
* Update the first document matching the query conditions
|
|
624
640
|
* @param updateData - Data to update
|
|
@@ -811,6 +827,12 @@ declare class BatchUpdater {
|
|
|
811
827
|
* @returns Object mapping field values to their document counts
|
|
812
828
|
*/
|
|
813
829
|
countBy(field: string): Promise<CountByResult>;
|
|
830
|
+
/**
|
|
831
|
+
* Group matching documents by a specific field value
|
|
832
|
+
* @param field - Field path to group by
|
|
833
|
+
* @returns Object mapping field values to arrays of matching documents { id, data }
|
|
834
|
+
*/
|
|
835
|
+
groupBy(field: string): Promise<GroupByResult>;
|
|
814
836
|
/**
|
|
815
837
|
* Import documents from a JSON file into Firestore
|
|
816
838
|
* @param filePath - Path to the JSON file to import
|
|
@@ -915,4 +937,4 @@ declare function isValidUpdateData(value: any): value is Record<string, any>;
|
|
|
915
937
|
*/
|
|
916
938
|
declare function formatError(error: unknown, context?: string): string;
|
|
917
939
|
|
|
918
|
-
export { type AggregateResult, type AggregateSpec, BatchUpdater, type BulkCreateInput, type BulkCreateOptions, type BulkCreateResult, type BulkDeleteOptions, type BulkDeleteResult, type BulkUpdateInput, type BulkUpdateOptions, type BulkUpdateResult, type CopyToOptions, type CopyToResult, type CountByResult, type CountResult, type CreateDocumentInput, type CreateOneResult, type CreateOptions, type CreateResult, type DeleteOptions, type DeleteResult, type DocumentSnapshot, type DryRunResult, type FieldStatsResult, type FieldValueResult, type FromJSONOptions, type FromJSONResult, type LogEntry, type LogOptions, type OperationLog, type OrderByCondition, type PaginateOptions, type PaginateResult, type PreviewResult, type ProgressInfo, type ToJSONOptions, type ToJSONResult, type TransformFn, type TransformOptions, type TransformResult, type UpdateOptions, type UpdateResult, type UpsertOptions, type UpsertResult, type WhereCondition, calculateProgress, createLogCollector, formatError, formatOperationLog, getAffectedFields, isValidUpdateData, mergeUpdateData, writeOperationLog };
|
|
940
|
+
export { type AggregateResult, type AggregateSpec, BatchUpdater, type BulkCreateInput, type BulkCreateOptions, type BulkCreateResult, type BulkDeleteOptions, type BulkDeleteResult, type BulkUpdateInput, type BulkUpdateOptions, type BulkUpdateResult, type CopyToOptions, type CopyToResult, type CountByResult, type CountResult, type CreateDocumentInput, type CreateOneResult, type CreateOptions, type CreateResult, type DeleteOptions, type DeleteResult, type DocumentSnapshot, type DryRunResult, type FieldStatsResult, type FieldValueResult, type FromJSONOptions, type FromJSONResult, type GroupByResult, type LogEntry, type LogOptions, type OperationLog, type OrderByCondition, type PaginateOptions, type PaginateResult, type PreviewResult, type ProgressInfo, type ToJSONOptions, type ToJSONResult, type TransformFn, type TransformOptions, type TransformResult, type UpdateOptions, type UpdateResult, type UpsertOptions, type UpsertResult, type WhereCondition, calculateProgress, createLogCollector, formatError, formatOperationLog, getAffectedFields, isValidUpdateData, mergeUpdateData, writeOperationLog };
|
package/dist/index.d.ts
CHANGED
|
@@ -472,6 +472,16 @@ interface FieldStatsResult {
|
|
|
472
472
|
interface CountByResult {
|
|
473
473
|
[value: string]: number;
|
|
474
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* Result of groupBy operation
|
|
477
|
+
* Field value → array of matching documents
|
|
478
|
+
*/
|
|
479
|
+
interface GroupByResult {
|
|
480
|
+
[value: string]: {
|
|
481
|
+
id: string;
|
|
482
|
+
data: Record<string, any>;
|
|
483
|
+
}[];
|
|
484
|
+
}
|
|
475
485
|
/**
|
|
476
486
|
* Options for fromJSON operation
|
|
477
487
|
*/
|
|
@@ -619,6 +629,12 @@ declare class BatchUpdater {
|
|
|
619
629
|
id: string;
|
|
620
630
|
data: Record<string, any>;
|
|
621
631
|
} | null>;
|
|
632
|
+
/**
|
|
633
|
+
* Check if a document with the given ID exists in the collection
|
|
634
|
+
* @param id - Document ID to check
|
|
635
|
+
* @returns true if the document exists, false otherwise
|
|
636
|
+
*/
|
|
637
|
+
has(id: string): Promise<boolean>;
|
|
622
638
|
/**
|
|
623
639
|
* Update the first document matching the query conditions
|
|
624
640
|
* @param updateData - Data to update
|
|
@@ -811,6 +827,12 @@ declare class BatchUpdater {
|
|
|
811
827
|
* @returns Object mapping field values to their document counts
|
|
812
828
|
*/
|
|
813
829
|
countBy(field: string): Promise<CountByResult>;
|
|
830
|
+
/**
|
|
831
|
+
* Group matching documents by a specific field value
|
|
832
|
+
* @param field - Field path to group by
|
|
833
|
+
* @returns Object mapping field values to arrays of matching documents { id, data }
|
|
834
|
+
*/
|
|
835
|
+
groupBy(field: string): Promise<GroupByResult>;
|
|
814
836
|
/**
|
|
815
837
|
* Import documents from a JSON file into Firestore
|
|
816
838
|
* @param filePath - Path to the JSON file to import
|
|
@@ -915,4 +937,4 @@ declare function isValidUpdateData(value: any): value is Record<string, any>;
|
|
|
915
937
|
*/
|
|
916
938
|
declare function formatError(error: unknown, context?: string): string;
|
|
917
939
|
|
|
918
|
-
export { type AggregateResult, type AggregateSpec, BatchUpdater, type BulkCreateInput, type BulkCreateOptions, type BulkCreateResult, type BulkDeleteOptions, type BulkDeleteResult, type BulkUpdateInput, type BulkUpdateOptions, type BulkUpdateResult, type CopyToOptions, type CopyToResult, type CountByResult, type CountResult, type CreateDocumentInput, type CreateOneResult, type CreateOptions, type CreateResult, type DeleteOptions, type DeleteResult, type DocumentSnapshot, type DryRunResult, type FieldStatsResult, type FieldValueResult, type FromJSONOptions, type FromJSONResult, type LogEntry, type LogOptions, type OperationLog, type OrderByCondition, type PaginateOptions, type PaginateResult, type PreviewResult, type ProgressInfo, type ToJSONOptions, type ToJSONResult, type TransformFn, type TransformOptions, type TransformResult, type UpdateOptions, type UpdateResult, type UpsertOptions, type UpsertResult, type WhereCondition, calculateProgress, createLogCollector, formatError, formatOperationLog, getAffectedFields, isValidUpdateData, mergeUpdateData, writeOperationLog };
|
|
940
|
+
export { type AggregateResult, type AggregateSpec, BatchUpdater, type BulkCreateInput, type BulkCreateOptions, type BulkCreateResult, type BulkDeleteOptions, type BulkDeleteResult, type BulkUpdateInput, type BulkUpdateOptions, type BulkUpdateResult, type CopyToOptions, type CopyToResult, type CountByResult, type CountResult, type CreateDocumentInput, type CreateOneResult, type CreateOptions, type CreateResult, type DeleteOptions, type DeleteResult, type DocumentSnapshot, type DryRunResult, type FieldStatsResult, type FieldValueResult, type FromJSONOptions, type FromJSONResult, type GroupByResult, type LogEntry, type LogOptions, type OperationLog, type OrderByCondition, type PaginateOptions, type PaginateResult, type PreviewResult, type ProgressInfo, type ToJSONOptions, type ToJSONResult, type TransformFn, type TransformOptions, type TransformResult, type UpdateOptions, type UpdateResult, type UpsertOptions, type UpsertResult, type WhereCondition, calculateProgress, createLogCollector, formatError, formatOperationLog, getAffectedFields, isValidUpdateData, mergeUpdateData, writeOperationLog };
|
package/dist/index.js
CHANGED
|
@@ -373,6 +373,25 @@ var BatchUpdater = class {
|
|
|
373
373
|
data: docSnapshot.data()
|
|
374
374
|
};
|
|
375
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* Check if a document with the given ID exists in the collection
|
|
378
|
+
* @param id - Document ID to check
|
|
379
|
+
* @returns true if the document exists, false otherwise
|
|
380
|
+
*/
|
|
381
|
+
async has(id) {
|
|
382
|
+
this.validateSetup();
|
|
383
|
+
if (!id || typeof id !== "string") {
|
|
384
|
+
throw new Error("Document ID is required");
|
|
385
|
+
}
|
|
386
|
+
if (this.isCollectionGroup) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
"has() cannot be used with collectionGroup(). Use exists() with where conditions instead."
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
const docRef = this.firestore.collection(this.collectionPath).doc(id);
|
|
392
|
+
const docSnapshot = await docRef.get();
|
|
393
|
+
return docSnapshot.exists;
|
|
394
|
+
}
|
|
376
395
|
/**
|
|
377
396
|
* Update the first document matching the query conditions
|
|
378
397
|
* @param updateData - Data to update
|
|
@@ -1450,6 +1469,31 @@ var BatchUpdater = class {
|
|
|
1450
1469
|
}
|
|
1451
1470
|
return counts;
|
|
1452
1471
|
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Group matching documents by a specific field value
|
|
1474
|
+
* @param field - Field path to group by
|
|
1475
|
+
* @returns Object mapping field values to arrays of matching documents { id, data }
|
|
1476
|
+
*/
|
|
1477
|
+
async groupBy(field) {
|
|
1478
|
+
this.validateSetup();
|
|
1479
|
+
if (!field || typeof field !== "string") {
|
|
1480
|
+
throw new Error("Field path is required");
|
|
1481
|
+
}
|
|
1482
|
+
const query = this.buildQuery();
|
|
1483
|
+
const snapshot = await query.get();
|
|
1484
|
+
const groups = {};
|
|
1485
|
+
for (const doc of snapshot.docs) {
|
|
1486
|
+
const data = doc.data();
|
|
1487
|
+
const value = this.getNestedValue(data, field);
|
|
1488
|
+
if (value === void 0 || value === null) continue;
|
|
1489
|
+
const key = String(value);
|
|
1490
|
+
if (!groups[key]) {
|
|
1491
|
+
groups[key] = [];
|
|
1492
|
+
}
|
|
1493
|
+
groups[key].push({ id: doc.id, data });
|
|
1494
|
+
}
|
|
1495
|
+
return groups;
|
|
1496
|
+
}
|
|
1453
1497
|
/**
|
|
1454
1498
|
* Import documents from a JSON file into Firestore
|
|
1455
1499
|
* @param filePath - Path to the JSON file to import
|
package/dist/index.mjs
CHANGED
|
@@ -328,6 +328,25 @@ var BatchUpdater = class {
|
|
|
328
328
|
data: docSnapshot.data()
|
|
329
329
|
};
|
|
330
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Check if a document with the given ID exists in the collection
|
|
333
|
+
* @param id - Document ID to check
|
|
334
|
+
* @returns true if the document exists, false otherwise
|
|
335
|
+
*/
|
|
336
|
+
async has(id) {
|
|
337
|
+
this.validateSetup();
|
|
338
|
+
if (!id || typeof id !== "string") {
|
|
339
|
+
throw new Error("Document ID is required");
|
|
340
|
+
}
|
|
341
|
+
if (this.isCollectionGroup) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
"has() cannot be used with collectionGroup(). Use exists() with where conditions instead."
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
const docRef = this.firestore.collection(this.collectionPath).doc(id);
|
|
347
|
+
const docSnapshot = await docRef.get();
|
|
348
|
+
return docSnapshot.exists;
|
|
349
|
+
}
|
|
331
350
|
/**
|
|
332
351
|
* Update the first document matching the query conditions
|
|
333
352
|
* @param updateData - Data to update
|
|
@@ -1405,6 +1424,31 @@ var BatchUpdater = class {
|
|
|
1405
1424
|
}
|
|
1406
1425
|
return counts;
|
|
1407
1426
|
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Group matching documents by a specific field value
|
|
1429
|
+
* @param field - Field path to group by
|
|
1430
|
+
* @returns Object mapping field values to arrays of matching documents { id, data }
|
|
1431
|
+
*/
|
|
1432
|
+
async groupBy(field) {
|
|
1433
|
+
this.validateSetup();
|
|
1434
|
+
if (!field || typeof field !== "string") {
|
|
1435
|
+
throw new Error("Field path is required");
|
|
1436
|
+
}
|
|
1437
|
+
const query = this.buildQuery();
|
|
1438
|
+
const snapshot = await query.get();
|
|
1439
|
+
const groups = {};
|
|
1440
|
+
for (const doc of snapshot.docs) {
|
|
1441
|
+
const data = doc.data();
|
|
1442
|
+
const value = this.getNestedValue(data, field);
|
|
1443
|
+
if (value === void 0 || value === null) continue;
|
|
1444
|
+
const key = String(value);
|
|
1445
|
+
if (!groups[key]) {
|
|
1446
|
+
groups[key] = [];
|
|
1447
|
+
}
|
|
1448
|
+
groups[key].push({ id: doc.id, data });
|
|
1449
|
+
}
|
|
1450
|
+
return groups;
|
|
1451
|
+
}
|
|
1408
1452
|
/**
|
|
1409
1453
|
* Import documents from a JSON file into Firestore
|
|
1410
1454
|
* @param filePath - Path to the JSON file to import
|