额外
复合类型

复合类型

自 v0.6.7 起可用

当使用 MongoDB 时,您可能需要使用 嵌入式文档 (在新标签页中打开),Prisma 称之为“复合类型”。Prisma Client Rust 会在您使用复合类型时生成字段和类型模块,允许您对它们执行 CRUD 操作。

这些文档仅关注 Rust 特定的细节,请查看 Prisma 的文档 (在新标签页中打开) 以获取全面的指南,其中包括所有可用操作、过滤器以及一些需要注意的事项的列表。

所有示例都将使用以下模式

model Product {
  id     String  @id @default(auto()) @map("_id") @db.ObjectId
  name   String  @unique
  price  Float
  colors Color[]
  sizes  Size[]
  photos Photo[]
  orders Order[]
}
 
model Order {
  id              String   @id @default(auto()) @map("_id") @db.ObjectId
  product         Product  @relation(fields: [productId], references: [id])
  color           Color
  size            Size
  shippingAddress Address
  billingAddress  Address?
  productId       String   @db.ObjectId
}
 
enum Color {
  Red
  Green
  Blue
}
 
enum Size {
  Small
  Medium
  Large
  XLarge
}
 
type Photo {
  height Int    @default(200)
  width  Int    @default(100)
  url    String
}
 
type Address {
  street String
  city   String
  zip    String
}

过滤

要查找具有匹配复合类型的记录,请将字段的过滤函数与类型的字段模块的 equals 函数结合使用。

let orders = client
	.order()
	.find_many(vec![
		order::shipping_adress::is(vec![
			address::street::equals("555 Candy Cane Lane".to_string()),
			address::city::equals("Wonderland".to_string()),
			address::street::equals("52337".to_string()),
		])
	])
	.exec()
	.await?;

创建

要创建新的复合类型,请使用其 create 类型模块函数。

let order = client
	.order()
	.create(
		..,
		vec![
			order::shipping_adress::set(
				address::create(
					"1084 Candycane Lane".to_string(),
					"Silverlake".to_string(),
					"84323".to_string(),
					vec![]
				)
			),
			order::billing_address::set(None),
			order::photos::set(vec![
				photo::create(100, 200, "photo.jpg".to_string());
				3
			])
		]
	)

更新

要更新现有的复合类型,可以使用一些可用的类型模块函数。

单个字段

// overwrite entire type
order::shipping_address::set(address::create(
	..
))
 
// update certain fields
order::shipping_address::update(vec![
	address::zip::set("41232".to_string())
])
 
// attempt to update certain fields,
// creating a new type if one doesn't exist
order::billing_address::upsert(
	address::create(..),
	// list of updates to attempt to apply
	vec![address::zip::set("41232".to_string())]
)
 
// removes the field entirely
order::billing_address::unset()

列表字段

// overwrite entire list
product::photos::set(vec![
	photo::create(..),
	photo::create(..),
])
 
// push values to the end of the list
product::photos::push(vec![
	photo::create(..),
	photo::create(..),
])
 
// update multiple values in the list
product::photos::update_many(
	// filter
	vec![photo::url::equals("1.jpg".to_string())],
	// updates
	vec![photo::url::set("2.jpg".to_string())]
)
 
// update multiple values from the list
product::photos::delete_many(
	// filter
	vec![photo::url::equals("1.jpg".to_string())],
)

排序

可以根据复合类型中字段的顺序对结果进行排序。

use prisma_client_rust::Direction;
 
let orders = client
	.order()
	.find_many(vec![])
	.order_by(order::shipping_address::order(
		address::city::order(SortOrder::Asc)
	))
	.exec()
	.await?;