全文检索
Prisma Client 支持 2.30.0 及更高版本的 PostgreSQL 数据库以及 3.8.0 及更高版本的 MySQL 数据库的全文搜索。启用全文搜索 (FTS) 后,你可以通过在数据库列中搜索文本来向你的应用添加搜索功能。
¥Prisma Client supports full-text search for PostgreSQL databases in versions 2.30.0 and later, and MySQL databases in versions 3.8.0 and later. With full-text search (FTS) enabled, you can add search functionality to your application by searching for text within a database column.
在 Prisma v6 中,FTS 一直是 在 MySQL 上升级为通用可用性。它仍保留在 PostgreSQL 的预览版中,并且需要使用 fullTextSearchPostgres
预览功能标志。
¥In Prisma v6, FTS has been promoted to General Availability on MySQL. It still remains in Preview for PostgreSQL and requires using the fullTextSearchPostgres
Preview feature flag.
为 PostgreSQL 启用全文搜索
¥Enabling full-text search for PostgreSQL
全文搜索 API 目前是预览功能。要启用此功能,请执行以下步骤:
¥The full-text search API is currently a Preview feature. To enable this feature, carry out the following steps:
-
更新架构中的
previewFeatures
块以包含fullTextSearchPostgres
预览功能标志:¥Update the
previewFeatures
block in your schema to include thefullTextSearchPostgres
preview feature flag:schema.prismagenerator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearchPostgres"]
} -
生成 Prisma 客户端:
¥Generate Prisma Client:
npx prisma generate
重新生成客户端后,新的 search
字段将在模型上创建的任何 String
字段上可用。例如,以下搜索将返回包含单词 '猫' 的所有帖子。
¥After you regenerate your client, a new search
field will be available on any String
fields created on your models. For example, the following search will return all posts that contain the word 'cat'.
// All posts that contain the word 'cat'.
const result = await prisma.posts.findMany({
where: {
body: {
search: 'cat',
},
},
})
注意:PostgreSQL 的全文搜索功能中目前有一个 已知问题。如果你观察到搜索查询速度缓慢,你可以 使用原始 SQL 优化你的查询。
¥Note: There currently is a known issue in the full-text search feature for PostgreSQL. If you observe slow search queries, you can optimize your query with raw SQL.
查询数据库
¥Querying the database
search
字段在后台使用数据库的原生查询功能。这意味着可用的确切查询运算符也是特定于数据库的。
¥The search
field uses the database's native querying capabilities under the hood. This means that the exact query operators available are also database-specific.
PostgreSQL
以下示例演示了 PostgreSQL 'and' (&
) 和 'or' (|
) 运算符的使用:
¥The following examples demonstrate the use of the PostgreSQL 'and' (&
) and 'or' (|
) operators:
// All posts that contain the words 'cat' or 'dog'.
const result = await prisma.posts.findMany({
where: {
body: {
search: 'cat | dog',
},
},
})
// All drafts that contain the words 'cat' and 'dog'.
const result = await prisma.posts.findMany({
where: {
status: 'Draft',
body: {
search: 'cat & dog',
},
},
})
要了解查询格式的工作原理,请考虑以下文本:
¥To get a sense of how the query format works, consider the following text:
"敏捷的棕色狐狸跳过了懒狗"
¥"The quick brown fox jumps over the lazy dog"
以下是以下查询与该文本匹配的方式:
¥Here's how the following queries would match that text:
查询 | 匹配? | 说明 |
---|---|---|
fox & dog | 是的 | 文本包含 'fox' 和 'dog' |
dog & fox | 是的 | 文本包含 'dog' 和 'fox' |
dog & cat | 不 | 文本包含 'dog' 但不包含 '猫' |
!cat | 是的 | '猫' 不在文本中 |
fox | cat | 是的 | 文本包含 'fox' 或 '猫' |
cat | pig | 不 | 文本不包含 '猫' 或 '猪' |
fox <-> dog | 是的 | 文本中 'dog' 位于 'fox' 之后 |
dog <-> fox | 不 | 文本中 'fox' 不在 'dog' 之后 |
有关支持的全部操作范围,请参阅 PostgreSQL 全文搜索文档。
¥For the full range of supported operations, see the PostgreSQL full text search documentation.
MySQL
以下示例演示了 MySQL 'and' (+
) 和 'not' (-
) 运算符的使用:
¥The following examples demonstrate use of the MySQL 'and' (+
) and 'not' (-
) operators:
// All posts that contain the words 'cat' or 'dog'.
const result = await prisma.posts.findMany({
where: {
body: {
search: 'cat dog',
},
},
})
// All posts that contain the words 'cat' and not 'dog'.
const result = await prisma.posts.findMany({
where: {
body: {
search: '+cat -dog',
},
},
})
// All drafts that contain the words 'cat' and 'dog'.
const result = await prisma.posts.findMany({
where: {
status: 'Draft',
body: {
search: '+cat +dog',
},
},
})
要了解查询格式的工作原理,请考虑以下文本:
¥To get a sense of how the query format works, consider the following text:
"敏捷的棕色狐狸跳过了懒狗"
¥"The quick brown fox jumps over the lazy dog"
以下是以下查询与该文本匹配的方式:
¥Here's how the following queries would match that text:
查询 | 匹配? | 描述 |
---|---|---|
+fox +dog | 是的 | 文本包含 'fox' 和 'dog' |
+dog +fox | 是的 | 文本包含 'dog' 和 'fox' |
+dog -cat | 是的 | 文本包含 'dog' 但不包含 '猫' |
-cat | 不 | 减号运算符不能单独使用(参见下面的注释) |
fox dog | 是的 | 文本包含 'fox' 或 'dog' |
quic* | 是的 | 文本包含以 'quic' 开头的单词 |
quick fox @2 | 是的 | 'fox' 在 'quick' 的 2 个字距离内开始 |
fox dog @2 | 不 | 'dog' 不在 'fox' 的 2 个字距离内开始 |
"jumps over" | 是的 | 文本包含整个短语 '跳过' |
注意:这 - 运算符仅用于排除与其他搜索词匹配的行。因此,布尔模式搜索仅包含前面的术语 - 返回空结果。它不会返回“除包含任何排除术语的行之外的所有行”。
¥Note: The - operator acts only to exclude rows that are otherwise matched by other search terms. Thus, a boolean-mode search that contains only terms preceded by - returns an empty result. It does not return “all rows except those containing any of the excluded terms.”
MySQL 还有 >
、<
和 ~
运算符用于改变搜索结果的排名顺序。例如,考虑以下两条记录:
¥MySQL also has >
, <
and ~
operators for altering the ranking order of search results. As an example, consider the following two records:
1.
2.
查询 | 结果 | 描述 |
---|---|---|
fox ~cat | 返回 1。首先,然后 2。 | 返回包含 'fox' 的所有记录,但将包含 '猫' 的记录排名较低 |
fox (<cat >dog) | 返回 1。首先,然后 2。 | 返回包含 'fox' 的所有记录,但包含 '猫' 的记录的排名低于包含 'dog' 的行 |
有关支持的全部操作范围,请参阅 MySQL 全文搜索文档。
¥For the full range of supported operations, see the MySQL full text search documentation.
按 _relevance
对结果排序
¥Sorting results by _relevance
按相关性排序仅适用于 PostgreSQL 和 MySQL。
¥Sorting by relevance is only available for PostgreSQL and MySQL.
除了 Prisma 客户端的默认 orderBy
行为 之外,全文搜索还添加了按与给定字符串或多个字符串的相关性进行排序。例如,如果你想根据帖子与标题中术语 'database'
的相关性对帖子进行排序,你可以使用以下命令:
¥In addition to Prisma Client's default orderBy
behavior, full-text search also adds sorting by relevance to a given string or strings. As an example, if you wanted to order posts by their relevance to the term 'database'
in their title, you could use the following:
const posts = await prisma.post.findMany({
orderBy: {
_relevance: {
fields: ['title'],
search: 'database',
sort: 'asc'
},
},
})
添加索引
¥Adding indexes
PostgreSQL
Prisma Client 目前不支持使用索引来加速全文搜索。有一个现有的 GitHub 问题 用于此目的。
¥Prisma Client does not currently support using indexes to speed up full text search. There is an existing GitHub Issue for this.
MySQL
对于 MySQL,有必要向使用 schema.prisma
文件中的 @@fulltext
参数搜索的任何列添加索引。
¥For MySQL, it is necessary to add indexes to any columns you search using the @@fulltext
argument in the schema.prisma
file.
在以下示例中,一个全文索引添加到 Blog
模型的 content
字段,另一个全文索引同时添加到 content
和 title
字段:
¥In the following example, one full text index is added to the content
field of the Blog
model, and another is added to both the content
and title
fields together:
generator client {
provider = "prisma-client-js"
}
model Blog {
id Int @unique
content String
title String
@@fulltext([content])
@@fulltext([content, title])
}
第一个索引允许在 content
字段中搜索单词 '猫' 的出现:
¥The first index allows searching the content
field for occurrences of the word 'cat':
const result = await prisma.blogs.findMany({
where: {
content: {
search: 'cat',
},
},
})
第二个索引允许在 content
和 title
字段中搜索单词 '猫' 在 content
中的出现以及 'food' 在 title
中的出现:
¥The second index allows searching both the content
and title
fields for occurrences of the word 'cat' in the content
and 'food' in the title
:
const result = await prisma.blogs.findMany({
where: {
content: {
search: 'cat',
},
title: {
search: 'food',
},
},
})
但是,如果你尝试单独搜索 title
,则搜索将失败,并出现错误 "找不到用于搜索的全文索引",消息代码为 P2030
,因为搜索需要两个字段上的索引。
¥However, if you try to search on title
alone, the search will fail with the error "Cannot find a fulltext index to use for the search" and the message code is P2030
, because the search requires an index on both fields.
使用原始 SQL 进行全文搜索
¥Full-text search with raw SQL
全文搜索目前处于预览阶段,由于 已知问题,你可能会遇到搜索查询缓慢的情况。如果是这样,你可以使用 TypedSQL 优化你的查询。
¥Full-text search is currently in Preview, and due to a known issue, you might experience slow search queries. If so, you can optimize your query using TypedSQL.
PostgreSQL
使用 TypedSQL,你可以使用 PostgreSQL 的 to_tsvector
和 to_tsquery
来表达你的搜索查询。
¥With TypedSQL, you can use PostgreSQL's to_tsvector
and to_tsquery
to express your search query.
- fullTextSearch.sql
- index.ts
SELECT * FROM "Blog" WHERE to_tsvector('english', "Blog"."content") @@ to_tsquery('english', ${term});
import { fullTextSearch } from "@prisma/client/sql"
const term = `cat`
const result = await prisma.$queryRawTyped(fullTextSearch(term))
注意:根据你的语言偏好,你可以在 SQL 语句中将
english
与另一种语言交换。¥Note: Depending on your language preferences, you may exchange
english
against another language in the SQL statement.
如果你想在搜索词中包含通配符,可以按以下步骤操作:
¥If you want to include a wildcard in your search term, you can do this as follows:
- fullTextSearch.sql
- index.ts
SELECT * FROM "Blog" WHERE to_tsvector('english', "Blog"."content") @@ to_tsquery('english', ${term});
const term = `cat:*`
const result = await prisma.$queryRawTyped(fullTextSearch(term))
MySQL
在 MySQL 中,你可以按如下方式表达搜索查询:
¥In MySQL, you can express your search query as follows:
- fullTextSearch.sql
- index.ts
SELECT * FROM Blog WHERE MATCH(content) AGAINST(${term} IN NATURAL LANGUAGE MODE);
const term = `cat`
const result = await prisma.$queryRawTyped(fullTextSearch(term))