imean-cassandra-orm 3.3.2 → 4.0.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.
Files changed (6) hide show
  1. package/README.md +125 -337
  2. package/dist/mod.cjs +1077 -2340
  3. package/dist/mod.d.cts +198 -326
  4. package/dist/mod.d.ts +198 -326
  5. package/dist/mod.js +1076 -2338
  6. package/package.json +10 -9
package/README.md CHANGED
@@ -1,337 +1,125 @@
1
- # IMean Cassandra ORM
2
-
3
- 一个基于 Zod 的 Cassandra ORM,提供类型安全的 schema 定义和数据库操作。
4
-
5
- ## 特性
6
-
7
- - 🎯 **类型安全**: 基于 Zod 的 schema 验证和 TypeScript 类型推断,确保入库和出库的数据类型安全。
8
- - 🔧 **自动 CQL 生成**: 自动生成 Cassandra CQL 语句,无需手写。
9
- - 📊 **完整 CRUD**: 支持插入、查询、更新、删除操作。
10
- - 🚀 **批量操作**: 支持批量插入,提升性能。
11
- - 🎨 **简洁 API**: 简单易用的 API 设计,通过 Client 统一管理模型。
12
- - 🔄 **Schema 同步**: 自动创建和同步 keyspace 和表结构。
13
- - ⚙️ **Keyspace 配置**: 支持自定义复制策略和配置。
14
- - 🤖 **自动序列化**: 自动处理复杂类型(如 JSON 对象、数组)的序列化和反序列化。
15
- - 📊 **ClickHouse 双写**: 可选的 ClickHouse 双写功能,支持实时数据分析和自动表结构同步。
16
-
17
- ## 安装
18
-
19
- ```bash
20
- npm install imean-cassandra-orm
21
- ```
22
-
23
- ## 快速开始
24
-
25
- ### 1. 定义 Schema
26
-
27
- 使用 `TableSchema` 和 `zod` 来定义你的表结构。ORM 会根据你的定义自动推断类型和生成数据库表。
28
-
29
- ```typescript
30
- import { z } from "zod";
31
- import { TableSchema } from "imean-cassandra-orm";
32
-
33
- // 定义用户表 schema
34
- const userSchema = new TableSchema({
35
- fields: {
36
- user_id: z.string(),
37
- email: z.string().email(),
38
- name: z.string(),
39
- age: z.number().int().positive(),
40
- is_active: z.boolean(),
41
- metadata: z.record(z.any()), // 可以是任意复杂的对象
42
- created_at: z.date(),
43
- },
44
- partitionKey: ["user_id"],
45
- tableName: "users",
46
- keyspace: "my_app_keyspace",
47
- });
48
-
49
- // 定义帖子表 schema(带聚类键)
50
- const postSchema = new TableSchema({
51
- fields: {
52
- user_id: z.string(),
53
- post_id: z.string(),
54
- title: z.string(),
55
- content: z.string(),
56
- tags: z.array(z.string()), // 数组类型
57
- published_at: z.date(),
58
- },
59
- partitionKey: ["user_id"],
60
- clusteringKey: { post_id: "desc" }, // 按 post_id 降序
61
- tableName: "posts",
62
- keyspace: "my_app_keyspace",
63
- });
64
- ```
65
-
66
- ### 2. 创建 Client 和模型
67
-
68
- `Client` 是所有操作的入口。你需要先创建一个 `Client` 实例,然后用它来创建 `Model` 实例。
69
-
70
- ```typescript
71
- import { Client } from "imean-cassandra-orm";
72
-
73
- // 1. 创建 Client 实例
74
- const client = new Client({
75
- contactPoints: ["localhost"],
76
- localDataCenter: "datacenter1",
77
- });
78
-
79
- // 2. 连接到 Cassandra
80
- await client.connect();
81
-
82
- // 3. (可选) 删除旧的 keyspace 以进行全新测试
83
- await client.dropKeyspace("my_app_keyspace");
84
-
85
- // 4. 通过 Client 创建模型实例
86
- const userModel = client.createModel(userSchema);
87
- const postModel = client.createModel(postSchema);
88
-
89
- // 5. 同步所有模型的 Schema
90
- // 这会确保 keyspace 和所有相关的表都已创建
91
- // 如果启用了双写,也会同步 ClickHouse 表结构
92
- await client.syncSchema();
93
- ```
94
-
95
- `client.syncSchema()` 会自动处理所有已创建模型的 schema 同步,你不再需要为每个模型单独调用 `syncSchema()`。
96
-
97
- ### 3. 基本操作
98
-
99
- 模型实例提供了完整的 CRUD API。
100
-
101
- ```typescript
102
- // 插入数据 (自动序列化 metadata 对象)
103
- const userData = {
104
- user_id: "user1",
105
- email: "user1@example.com",
106
- name: "张三",
107
- age: 25,
108
- is_active: true,
109
- metadata: { score: 95.5, level: 3, tags: ["vip"] },
110
- created_at: new Date(),
111
- };
112
- await userModel.insert(userData);
113
-
114
- // 查询数据 (自动反序列化 metadata)
115
- const foundUser = await userModel.findOne({ user_id: "user1" });
116
- console.log(foundUser?.metadata); // { score: 95.5, level: 3, tags: ["vip"] }
117
-
118
- // 更新数据
119
- await userModel.update(
120
- { user_id: "user1" },
121
- { name: "李四", age: 26 }
122
- );
123
-
124
- // 删除数据
125
- await userModel.delete({ user_id: "user1" });
126
- ```
127
-
128
- ### 4. 批量操作
129
-
130
- ```typescript
131
- // 批量插入
132
- const usersData = [
133
- {
134
- user_id: "user2",
135
- email: "user2@example.com",
136
- name: "王五",
137
- age: 30,
138
- is_active: true,
139
- metadata: { score: 88.0 },
140
- created_at: new Date(),
141
- },
142
- {
143
- user_id: "user3",
144
- email: "user3@example.com",
145
- name: "赵六",
146
- age: 28,
147
- is_active: false,
148
- metadata: { score: 79.2 },
149
- created_at: new Date(),
150
- },
151
- ];
152
- await userModel.batchInsert(usersData);
153
- ```
154
-
155
- ### 5. 使用聚类键
156
-
157
- 当你的 schema 定义了 `clusteringKey` 时,你可以在查询、更新和删除操作中指定它。
158
-
159
- ```typescript
160
- // 插入带聚类键的数据
161
- const postData = {
162
- user_id: "user1",
163
- post_id: "post1",
164
- title: "我的第一篇帖子",
165
- content: "这是内容...",
166
- tags: ["技术", "编程"],
167
- published_at: new Date(),
168
- };
169
- await postModel.insert(postData);
170
-
171
- // 查询特定帖子
172
- const post = await postModel.findOne(
173
- { user_id: "user1" },
174
- { post_id: "post1" } // 指定聚类键
175
- );
176
-
177
- // 更新特定帖子
178
- await postModel.update(
179
- { user_id: "user1" },
180
- { title: "更新后的标题" },
181
- { post_id: "post1" } // 指定聚类键
182
- );
183
-
184
- // 删除特定帖子
185
- await postModel.delete(
186
- { user_id: "user1" },
187
- { post_id: "post1" } // 指定聚类键
188
- );
189
- ```
190
-
191
- ### 6. 类型安全与校验
192
-
193
- ORM 会在数据返回时使用 Zod schema 进行校验,确保你得到的数据是类型安全的。
194
-
195
- ```typescript
196
- // 从数据库返回的数据
197
- const userFromDb = await userModel.findOne({ user_id: "user1" });
198
-
199
- // userFromDb 的类型是根据 userSchema 推断出来的,具有完整的类型提示
200
- if (userFromDb) {
201
- console.log(userFromDb.name.toUpperCase());
202
- }
203
-
204
- // 如果数据库中的数据不符合 schema(例如,手动修改了数据库),
205
- // 在查询时会抛出 ZodError,防止脏数据进入你的应用。
206
- ```
207
-
208
- ## ClickHouse 双写功能
209
-
210
- 框架支持可选的 ClickHouse 双写功能,可以将 Cassandra 的操作同步到 ClickHouse 中用于分析查询。
211
-
212
- ### 配置双写功能
213
-
214
- ```typescript
215
- import { Client } from "imean-cassandra-orm";
216
-
217
- const client = new Client({
218
- contactPoints: ["localhost"],
219
- localDataCenter: "datacenter1",
220
- keyspace: "my_keyspace",
221
- dualWrite: {
222
- enabled: true,
223
- clickhouse: {
224
- host: "localhost",
225
- port: 8123,
226
- username: "default",
227
- password: "",
228
- database: "analytics",
229
- },
230
- operations: {
231
- insert: true,
232
- update: true,
233
- delete: true,
234
- },
235
- errorHandling: "log", // 'ignore' | 'log' | 'throw'
236
- debug: true,
237
- },
238
- });
239
- ```
240
-
241
- ### 使用双写功能
242
-
243
- 启用双写后,所有的插入、更新、删除操作都会自动同步到 ClickHouse:
244
-
245
- ```typescript
246
- // 连接数据库
247
- await client.connect();
248
-
249
- // 同步 schema(会自动同步到 ClickHouse)
250
- await client.syncSchema();
251
-
252
- // 创建模型
253
- const UserModel = client.createModel(userSchema);
254
-
255
- // 插入数据(会自动双写到 ClickHouse)
256
- await UserModel.insert({
257
- user_id: "user1",
258
- email: "user1@example.com",
259
- name: "张三",
260
- age: 25,
261
- is_active: true,
262
- created_at: new Date(),
263
- });
264
-
265
- // 批量插入(会自动双写到 ClickHouse)
266
- await UserModel.batchInsert([...]);
267
-
268
- // 更新数据(会自动双写到 ClickHouse)
269
- await UserModel.update({ user_id: "user1" }, { age: 26 });
270
-
271
- // 删除数据(会自动双写到 ClickHouse)
272
- await UserModel.delete({ user_id: "user1" });
273
- ```
274
-
275
- ### 检查双写状态
276
-
277
- ```typescript
278
- if (client.isDualWriteEnabled()) {
279
- console.log("双写功能已启用");
280
- }
281
- ```
282
-
283
- 更多详细信息请参考 [双写功能文档](./docs/dual-write.md)。
284
-
285
- ## API 参考
286
-
287
- ### `Client`
288
-
289
- #### `new Client(options: cassandra.ClientOptions)`
290
-
291
- 创建一个新的 Client 实例。`options` 与 `cassandra-driver` 的 `ClientOptions` 相同。
292
-
293
- #### `client.connect(): Promise<void>`
294
-
295
- 连接到 Cassandra 集群。
296
-
297
- #### `client.createModel(schema: TableSchema): Model`
298
-
299
- 根据 `TableSchema` 创建一个 `Model` 实例。
300
-
301
- #### `client.syncSchema(): Promise<void>`
302
-
303
- 同步所有通过 `createModel` 创建的模型的 schema。
304
-
305
- #### `client.dropKeyspace(keyspace: string): Promise<void>`
306
-
307
- 删除一个 keyspace。
308
-
309
- ### `Model`
310
-
311
- #### `model.insert(data: T): Promise<void>`
312
-
313
- 插入一条数据。
314
-
315
- #### `model.batchInsert(data: T[]): Promise<void>`
316
-
317
- 批量插入多条数据。
318
-
319
- #### `model.find(partitionKey: PK): Promise<T[]>`
320
-
321
- 根据分区键查询多条数据。
322
-
323
- #### `model.findOne(partitionKey: PK, clusteringKey?: CK): Promise<T | null>`
324
-
325
- 根据分区键和(可选的)聚类键查询单条数据。
326
-
327
- #### `model.update(partitionKey: PK, data: Partial<T>, clusteringKey?: CK): Promise<void>`
328
-
329
- 更新一条数据。
330
-
331
- #### `model.delete(partitionKey: PK, clusteringKey?: CK): Promise<void>`
332
-
333
- 删除一条数据。
334
-
335
- ---
336
- 贡献者:imean
337
- License: MIT
1
+ # IMean Cassandra ORM (v2)
2
+
3
+ 基于 Zod 的 Cassandra ORM,提供类型安全的 schema 定义、CQL 编译、schema 同步与可选的 ClickHouse 双写。
4
+
5
+ ## 特性
6
+ - **类型安全**:基于 Zod 的 schema 验证与类型推断
7
+ - **自动 CQL 生成**:CRUD 与查询条件自动编译
8
+ - **Schema 同步**:自动创建与迁移表结构(含索引)
9
+ - **可选双写**:best‑effort 写入 ClickHouse
10
+ - **向量搜索**:支持 ANN 向量检索
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ npm install imean-cassandra-orm
16
+ ```
17
+
18
+ ## 快速开始
19
+
20
+ ### 1) 定义 Schema
21
+
22
+ ```ts
23
+ import { z } from "zod";
24
+ import { defineTable, Types } from "imean-cassandra-orm";
25
+
26
+ const userSchema = defineTable({
27
+ keyspace: "my_keyspace",
28
+ tableName: "users",
29
+ fields: {
30
+ user_id: z.string(),
31
+ email: z.string().email(),
32
+ name: z.string(),
33
+ age: z.number().int().positive(),
34
+ is_active: z.boolean(),
35
+ metadata: Types.json(),
36
+ created_at: z.date(),
37
+ },
38
+ partitionKey: ["user_id"],
39
+ });
40
+ ```
41
+
42
+ ### 2) 初始化 Client(推荐简化方式)
43
+
44
+ ```ts
45
+ import { createClientV2 } from "imean-cassandra-orm";
46
+
47
+ const { client, shutdown } = await createClientV2({
48
+ cassandra: {
49
+ contactPoints: ["127.0.0.1"],
50
+ localDataCenter: "datacenter1",
51
+ },
52
+ clickhouse: {
53
+ config: {
54
+ host: "127.0.0.1",
55
+ port: 8123,
56
+ username: "default",
57
+ password: "localpass",
58
+ database: "default",
59
+ },
60
+ },
61
+ });
62
+ ```
63
+
64
+ ### 3) 基本 CRUD
65
+
66
+ ```ts
67
+ const userModel = client.model(userSchema);
68
+ await userModel.syncSchema();
69
+
70
+ await userModel.insert({
71
+ user_id: "u1",
72
+ email: "u1@example.com",
73
+ name: "Alice",
74
+ age: 20,
75
+ is_active: true,
76
+ metadata: { score: 95 },
77
+ created_at: new Date(),
78
+ });
79
+
80
+ const found = await userModel.findOne({ user_id: "u1" });
81
+ await userModel.update({ user_id: "u1" }, { name: "Bob" });
82
+ await userModel.delete({ user_id: "u1" });
83
+ ```
84
+
85
+ ## Schema 同步
86
+
87
+ ```ts
88
+ await userModel.syncSchema(); // 自动创建/迁移表结构
89
+ ```
90
+
91
+ ## 查询语法
92
+
93
+ 详见 `QUERY_SYNTAX.md`。
94
+
95
+ ## 向量搜索
96
+
97
+ ```ts
98
+ const vectorSchema = defineTable({
99
+ keyspace: "my_keyspace",
100
+ tableName: "docs",
101
+ fields: {
102
+ id: z.string(),
103
+ embedding: Types.vector(128),
104
+ title: z.string(),
105
+ },
106
+ partitionKey: ["id"],
107
+ indexes: {
108
+ embedding: { similarity_function: "COSINE" },
109
+ },
110
+ });
111
+
112
+ const model = client.model(vectorSchema);
113
+ await model.syncSchema();
114
+
115
+ const results = await model.find(
116
+ { embedding: new Array(128).fill(0).map(() => Math.random()) },
117
+ { limit: 10 }
118
+ );
119
+ ```
120
+
121
+ ## 关闭连接
122
+
123
+ ```ts
124
+ await shutdown();
125
+ ```