document-dataply 0.0.2-alpha.2 → 0.0.2

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.md ADDED
@@ -0,0 +1,193 @@
1
+ # Document-Dataply
2
+
3
+ > [!WARNING]
4
+ > **This project is currently in the Alpha stage.**
5
+ > APIs and internal structures may change significantly between versions. Use with caution in production environments.
6
+
7
+ `document-dataply` is a high-performance document-oriented database library built on top of the [`dataply`](https://github.com/izure1/dataply) record storage engine. It provides a structured way to store, index, and query JSON-style documents, supporting transactions and complex field indexing.
8
+
9
+ ## Key Features
10
+
11
+ - **Document-Oriented**: Store and retrieve JSON-style documents.
12
+ - **B+Tree Indexing**: Supports high-performance lookups using a B+Tree indexing engine.
13
+ - **Deep Indexing**: Index nested object fields and specific array elements (e.g., `user.profile.name` or `tags.0`).
14
+ - **Flexible Indexing Policies**: Supports full re-indexing for existing data or incremental indexing for future data.
15
+ - **Transactions**: ACID-compliant transactions for atomic operations.
16
+ - **Rich Querying**: Supports comparison operators (`lt`, `gt`, `equal`, etc.) and pattern matching (`like`).
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install document-dataply
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```typescript
27
+ import { DocumentDataply } from 'document-dataply';
28
+
29
+ type MyDocument = {
30
+ name: string;
31
+ age: number;
32
+ tags: string[];
33
+ }
34
+
35
+ async function main() {
36
+ const db = new DocumentDataply<MyDocument>('my-database.db', {
37
+ wal: 'my-database.wal',
38
+ indices: {
39
+ name: true, // Index both existing and new data
40
+ age: false, // Index only new data
41
+ 'tags.0': true // Index the first element of the 'tags' array
42
+ }
43
+ });
44
+
45
+ // Initialize database
46
+ await db.init();
47
+
48
+ // Insert document
49
+ const id = await db.insert({
50
+ name: 'John Doe',
51
+ age: 30,
52
+ tags: ['admin', 'developer']
53
+ });
54
+
55
+ // Query document
56
+ const query = db.select({
57
+ name: 'John Doe',
58
+ age: { gte: 25 }
59
+ })
60
+
61
+ // Get all results
62
+ const allResults = await query.drain();
63
+ // Or iterate through results
64
+ for await (const doc of query.stream) {
65
+ console.log(doc);
66
+ }
67
+
68
+ console.log(allResults);
69
+
70
+ // Close database
71
+ await db.close();
72
+ }
73
+
74
+ main();
75
+ ```
76
+
77
+ ## Advanced Usage
78
+
79
+ ### Indexing Policies
80
+
81
+ When defining indices in the constructor, you can specify a boolean value.
82
+
83
+ - `true`: The library indexes all existing documents for that field during `init()`, and also indexes all subsequent insertions.
84
+ - `false`: The library only indexes documents inserted after this configuration.
85
+
86
+ > [!NOTE]
87
+ > `db.init()` automatically performs a backfilling process for fields marked as `true`.
88
+
89
+ ### Batch Insertion
90
+
91
+ To efficiently insert multiple documents, use the following:
92
+
93
+ ```typescript
94
+ const ids = await db.insertBatch([
95
+ { name: 'Alice', age: 25, tags: ['user'] },
96
+ { name: 'Bob', age: 28, tags: ['moderator'] }
97
+ ]);
98
+ ```
99
+
100
+ ### Querying
101
+
102
+ `document-dataply` supports various comparison operators.
103
+
104
+ | Operator | Description |
105
+ | :--- | :--- |
106
+ | `lt` | Less than |
107
+ | `lte` | Less than or equal to |
108
+ | `gt` | Greater than |
109
+ | `gte` | Greater than or equal to |
110
+ | `equal` | Equal to |
111
+ | `notEqual` | Not equal to |
112
+ | `like` | SQL-style pattern matching (e.g., `Jo%`) |
113
+ | `or` | If any value in the array is satisfied |
114
+
115
+ Example of a complex query:
116
+ ```typescript
117
+ const users = await db.select({
118
+ age: { gt: 18, lt: 65 },
119
+ 'address.city': 'Seoul',
120
+ tags: { or: ['vip', 'premium'] }
121
+ }).drain();
122
+ ```
123
+
124
+ > [!IMPORTANT]
125
+ > **Query Constraints**: Query conditions (`lt`, `gt`, `equal`, etc.) can only be used on fields explicitly indexed in the constructor.
126
+ >
127
+ > **If a field in the query is not indexed, that condition will be ignored.**
128
+ >
129
+ > If you need to filter by unindexed fields, you should first retrieve the documents and then use JavaScript's native `.filter()` method.
130
+ ```typescript
131
+ const results = await db.select({ /* indexed fields only */ }).drain();
132
+ const filtered = results.filter(doc => doc.unindexedField === 'some-value');
133
+ ```
134
+
135
+ ### Transactions
136
+
137
+ To ensure the atomicity of multiple operations, use transactions.
138
+
139
+ ```typescript
140
+ const tx = db.createTransaction();
141
+ try {
142
+ await db.insert({ name: 'Alice', age: 25 }, tx);
143
+ await db.insert({ name: 'Bob', age: 28 }, tx);
144
+ await tx.commit();
145
+ } catch (error) {
146
+ await tx.rollback();
147
+ throw error;
148
+ }
149
+ ```
150
+
151
+ ## Tips and Advanced Features
152
+
153
+ For more information on performance optimization and advanced features, see [TIPS.md](./docs/TIPS.md).
154
+
155
+ - **Query Optimization**: Automatic index selection for maximum performance.
156
+ - **Sorting and Pagination**: Detailed usage of `limit`, `orderBy`, and `sortOrder`.
157
+ - **Memory Management**: When to use `stream` vs `drain()`.
158
+ - **Performance**: Optimizing bulk data insertion using `insertBatch`.
159
+ - **Indexing Policies**: Deep dive into index backfilling and configuration.
160
+
161
+ ## API Reference
162
+
163
+ ### `new DocumentDataply<T>(file, options)`
164
+ Creates a new database instance. `T` defines the document structure.
165
+ `options.indices` is an object where keys are field names and values are booleans indicating whether to index.
166
+
167
+ ### `db.init()`
168
+ Initializes the database, sets up internal metadata, and prepares indices.
169
+
170
+ ### `db.insert(document, tx?)`
171
+ Inserts a single document. Returns the `_id` (`number`) of the document.
172
+
173
+ ### `db.insertBatch(documents, tx?)`
174
+ Inserts multiple documents efficiently. Returns an array of `_ids` (`number[]`).
175
+
176
+ ### `db.select(query, options?, tx?)`
177
+ Searches for documents matching the query.
178
+ Returns an object `{ stream, drain }`.
179
+ - `stream`: An async iterator to traverse results one by one.
180
+ - `drain()`: A promise that resolves to an array of all matching documents.
181
+
182
+ ### `db.getMetadata(tx?)`
183
+ Returns physical storage information (number of pages, number of rows, etc.).
184
+
185
+ ### `db.createTransaction()`
186
+ Returns a new `Transaction` object.
187
+
188
+ ### `db.close()`
189
+ Flushes changes and closes the database files.
190
+
191
+ ## License
192
+
193
+ MIT