Create and Query a View创建和查询视图
On this page本页内容
db.createCollection()
Syntax语法db.createView()
Syntax语法Restrictions限制Unsupported Operations不支持的操作Examples实例Populate the Collection填充集合Use db.createView() to Create a View使用db.createView()
创建视图Use db.createCollection() to Create a View使用db.createCollection()
创建视图Retrieve Medical Information for Roles Granted to the Current User检索授予当前用户的角色的医疗信息Retrieve Budget Documents for Roles Granted to the Current User检索授予当前用户的角色的预算文档Roles with the Same Name in Multiple Databases多个数据库中具有相同名称的角色Behavior行为Aggregation Optimizations聚合优化Resource Locking资源锁定
To create a view, use 要创建视图,请使用db.createCollection()
or db.createView()
.db.createCollection()
或db.createView()
。
View Names are Included in Collection List Output视图名称包含在集合列表输出中
Operations that list collections, such as 列出集合的操作,如db.getCollectionInfos()
and db.getCollectionNames()
, include views in their outputs.db.getCollectionInfos()
和db.getCollectionNames()
,在其输出中包含视图。
The view definition is public; i.e. 视图定义是公开的;db.getCollectionInfos()
and explain
operations on the view will include the pipeline that defines the view. db.getCollectionInfos()
和explain
对视图的操作将包括定义视图的管道。As such, avoid referring directly to sensitive fields and values in view definitions.因此,请避免直接引用视图定义中的敏感字段和值。
db.createCollection()
Syntax语法
db.createCollection(
"<viewName>",
{
"viewOn" : "<source>",
"pipeline" : [<pipeline>],
"collation" : { <collation> }
}
)
db.createView()
Syntax语法
db.createView(
"<viewName>",
"<source>",
[<pipeline>],
{
"collation" : { <collation> }
}
)
Restrictions限制
You must create views in the same database as the source collection.您必须在与源集合相同的数据库中创建视图。A view definition视图定义pipeline
cannot include the$out
or the$merge
stage.pipeline
不能包含$out
或$merge
阶段。This restriction also applies to embedded pipelines, such as pipelines used in此限制也适用于嵌入式管道,例如$lookup
or$facet
stages.$lookup
或$facet
阶段中使用的管道。You cannot rename a view once it is created.创建视图后,不能对其进行重命名。
Unsupported Operations不支持的操作
Some operations are not available with views:某些操作不可用于视图:
db.collection.mapReduce()
.$text
operator, since$text
operation in aggregation is valid only for the first stage.$text
运算符,因为聚合中的$text
操作仅对第一阶段有效。$geoNear
pipeline stage.管道阶段。Renaming a view.重命名视图。
For more information, see Supported Operations for Views.有关详细信息,请参阅支持的视图操作。
Examples实例
The first example populates a collection with student data and creates a view to query the data.第一个示例用学生数据填充集合,并创建一个视图来查询数据。
Populate the Collection填充集合
Create a 创建students
collection to use for this example:students
集合以用于此示例:
db.students.insertMany( [
{ sID: 22001, name: "Alex", year: 1, score: 4.0 },
{ sID: 21001, name: "bernie", year: 2, score: 3.7 },
{ sID: 20010, name: "Chris", year: 3, score: 2.5 },
{ sID: 22021, name: "Drew", year: 1, score: 3.2 },
{ sID: 17301, name: "harley", year: 6, score: 3.1 },
{ sID: 21022, name: "Farmer", year: 1, score: 2.2 },
{ sID: 20020, name: "george", year: 3, score: 2.8 },
{ sID: 18020, name: "Harley", year: 5, score: 2.8 },
] )
Use db.createView() to Create a View使用db.createView()
创建视图
Use 使用db.createView()
to create a view that is limited to first year students:db.createView()
创建一个仅限一年级学生使用的视图:
db.createView(
"firstYears",
"students",
[ { $match: { year: 1 } } ]
)
In the example:在示例中:
firstYears
is the name of the new view.是新视图的名称。students
is the collection the view is based on.是视图所基于的集合。$match
is an aggregation expression that matches first year students in the是一个聚合表达式,与students
collection.students
集合中的一年级学生相匹配。
Query the View查询视图
This example queries the view:此示例查询视图:
db.firstYears.find({}, { _id: 0 } )
The following output only contains the documents with data on first year students. 以下输出仅包含包含一年级学生数据的文档。The { _id: 0 }
projection suppresses the _id
field in the output.{ _id: 0 }
投影抑制输出中的_id
字段。
[
{ sID: 22001, name: 'Alex', year: 1, score: 4 },
{ sID: 22021, name: 'Drew', year: 1, score: 3.2 },
{ sID: 21022, name: 'Farmer', year: 1, score: 2.2 }
]
Projection Restrictions投影限制
find()
operations on views do not support the following Query and Projection Operators operators:视图上的操作不支持以下查询运算符和投影运算符:
Use db.createCollection() to Create a View使用db.createCollection()
创建视图
The db.createCollection()
method allows you to create a collection or a view with specific options.db.createCollection()
方法允许您创建具有特定选项的集合或视图。
The following example creates a 以下示例创建了一个graduateStudents
view. graduateStudents
视图。The view only contains documents selected by the 该视图仅包含由$match
stage. $match
阶段选择的文档。The optional collation setting determines the sort order.可选的排序规则设置确定排序顺序。
db.createCollection(
"graduateStudents",
{
viewOn: "students",
pipeline: [ { $match: { $expr: { $gt: [ "$year", 4 ] } } } ],
collation: { locale: "en", caseFirst: "upper" }
}
)
Collation Behavior排序规则行为
You can specify a default collation for a view at creation time.可以在创建时为视图指定默认排序规则。If no collation is specified, the view's default collation is the "simple" binary comparison collator.如果未指定排序规则,则视图的默认排序规则是"simple"
二进制比较排序规则。That is, the view does not inherit the collection's default collation.也就是说,视图不继承集合的默认排序规则。String comparisons on the view use the view's default collation.视图上的字符串比较使用视图的默认排序规则。An operation that attempts to change or override a view's default collation will fail with an error.尝试更改或覆盖视图的默认排序规则的操作将失败,并出现错误。If creating a view from another view, you cannot specify a collation that differs from the source view's collation.如果从其他视图创建视图,则不能指定与源视图的排序规则不同的排序规则。If performing an aggregation that involves multiple views, such as with如果执行涉及多个视图的聚合,例如使用$lookup
or$graphLookup
, the views must have the same collation.$lookup
或$graphLookup
,则这些视图必须具有相同的排序规则。
Query the View查询视图
The following example queries the view. 以下示例查询视图。The 为了清楚起见,$unset
stage removes the _id
field from the output for clarity.$unset
阶段从输出中删除了_id
字段。
db.graduateStudents.aggregate(
[
{ $sort: { name: 1 } },
{ $unset: [ "_id" ] }
]
)
When the output is sorted, the 对输出进行排序时,$sort
stage uses the collation ordering to sort uppercase letters before lowercase letters.$sort
阶段使用排序规则将大写字母排在小写字母之前。
[
{ sID: 18020, name: 'Harley', year: 5, score: 2.8 },
{ sID: 17301, name: 'harley', year: 6, score: 3.1 }
]
Retrieve Medical Information for Roles Granted to the Current User检索授予当前用户的角色的医疗信息
Starting in MongoDB 7.0, you can use the new 从MongoDB 7.0开始,您可以使用新的USER_ROLES
system variable to return user roles.USER_ROLES
系统变量来返回用户角色。
The example in this section shows users with limited access to fields in a collection containing medical information. 本节中的示例显示用户对包含医疗信息的集合中的字段的访问权限有限。The example uses a view that reads the current user roles from the 该示例使用的视图从USER_ROLES
system variable and hides fields based on the roles.USER_ROLES
系统变量中读取当前用户角色,并隐藏基于角色的字段。
The example creates these users:该示例创建了以下用户:
James
with aBilling
role who can access acreditCard
field.James
具有Billing
角色,可以访问creditCard
字段。Michelle
with aProvider
role who can access adiagnosisCode
field.Michelle
具有Provider
角色,可以访问diagnosisCode
字段。
Perform the following steps to create the roles, users, collection, and view:执行以下步骤以创建角色、用户、集合和视图:
Create the roles创建角色
Run:运行:
db.createRole( { role: "Billing", privileges: [ { resource: { db: "test",
collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
db.createRole( { role: "Provider", privileges: [ { resource: { db: "test",
collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
Create the users创建用户
Create users named 创建具有所需角色的名为James
and Michelle
with the required roles. James
和Michelle
的用户。Replace the 将test
database with your database name.test
数据库替换为您的数据库名称。
db.createUser( {
user: "James",
pwd: "js008",
roles: [
{ role: "Billing", db: "test" }
]
} )
db.createUser( {
user: "Michelle",
pwd: "me009",
roles: [
{ role: "Provider", db: "test" }
]
} )
Create the view创建视图
To use a system variable, add 要使用系统变量,请在变量名的开头添加$$
to the start of the variable name. $$
。Specify the 将USER_ROLES
system variable as $$USER_ROLES
.USER_ROLES
系统变量指定为$$USER_ROLES
。
The view reads the current user roles from the 该视图从USER_ROLES
system variable and hides fields based on the roles.USER_ROLES
系统变量中读取当前用户角色,并隐藏基于角色的字段。
Run:运行:
db.createView(
"medicalView", "medical",
[ {
$set: {
"diagnosisCode": {
$cond: {
if: { $in: [
"Provider", "$$USER_ROLES.role"
] },
then: "$diagnosisCode",
else: "$$REMOVE"
}
}
},
}, {
$set: {
"creditCard": {
$cond: {
if: { $in: [
"Billing", "$$USER_ROLES.role"
] },
then: "$creditCard",
else: "$$REMOVE"
}
}
}
} ]
)
The view example:视图示例:
includes the包括具有diagnosisCode
field for a user with theProvider
role.Provider
角色的用户的diagnosisCode
字段。includes the包括具有creditCard
field for a user with theBilling
role.Billing
角色的用户的creditCard
字段。uses使用$set
pipeline stages and$$REMOVE
to hide fields based on whether the user who queries the view has the matching role returned in$$USER_ROLES.role
.$set
管道阶段和$$REMOVE
根据查询视图的用户是否具有$$USER_ROLES.role
中返回的匹配角色来隐藏字段。
Perform the following steps to retrieve the information accessible to 执行以下步骤以检索James
:James
可访问的信息:
Examine the documents检查文件
James
has the Billing
role and sees the following documents, which include the creditCard
field but not the diagnosisCode
field:James
具有Billing
角色,并查看以下文档,其中包括creditCard
字段,但不包括diagnosisCode
字段:
[
{
_id: 0, patientName: 'Jack Jones',
creditCard: '1234-5678-9012-3456'
},
{
_id: 1, patientName: 'Mary Smith',
creditCard: '6541-7534-9637-3456'
}
]
Perform the following steps to retrieve the information accessible to 执行以下步骤以检索Michelle
:Michelle
可访问的信息:
Examine the documents检查文件
Michelle
has the Provider
role and sees the following documents, which include the diagnosisCode
field but not the creditCard
field:Michelle
具有Provider
角色,并查看以下文档,其中包括diagnosisCode
字段,但不包括creditCard
字段:
[
{ _id: 0, patientName: 'Jack Jones',
diagnosisCode: 'CAS 17' },
{ _id: 1, patientName: 'Mary Smith',
diagnosisCode: 'ACH 01' }
]
Retrieve Budget Documents for Roles Granted to the Current User检索授予当前用户的角色的预算文档
Starting in MongoDB 7.0, you can use the new 从MongoDB 7.0开始,您可以使用新的USER_ROLES
system variable to return user roles.USER_ROLES
系统变量来返回用户角色。
The scenario in this section shows users with various roles who have limited access to documents in a collection containing budget information.本节中的场景显示了具有各种角色的用户,他们对包含预算信息的集合中的文档的访问权限有限。
The scenario shows one possible use of 该场景显示了USER_ROLES
. USER_ROLES
的一种可能用途。The budget
collection contains documents with a field named allowedRoles
. budget
集合包含一个名为allowedRoles
的字段的文档。As you'll see in the following scenario, you can write queries that compare the user roles found in the 正如您在下面的场景中看到的那样,您可以编写查询,将allowedRoles
field with the roles returned by the USER_ROLES
system variable.allowedRoles
字段中的用户角色与USER_ROLES
系统变量返回的角色进行比较。
For another 有关另一个USER_ROLES
example scenario, see Retrieve Medical Information for Roles Granted to the Current User. USER_ROLES
示例场景,请参阅检索授予当前用户的角色的医疗信息。That example doesn't store the user roles in the document fields, as is done in the following example.该示例不会像下面的示例那样将用户角色存储在文档字段中。
For the budget scenario in this section, perform the following steps to create the roles, users, and 对于本节中的预算方案,请执行以下步骤来创建角色、用户和budget
collection:budget
集合:
Create the users创建用户
Create users named 创建具有所需角色的名为John
and Jane
with the required roles. John
和Jane
的用户。Replace the 将test
database with your database name.test
数据库替换为您的数据库名称。
db.createUser( {
user: "John",
pwd: "jn008",
roles: [
{ role: "Marketing", db: "test" },
{ role: "Development", db: "test" },
{ role: "Operations", db: "test" },
{ role: "read", db: "test" }
]
} )
db.createUser( {
user: "Jane",
pwd: "je009",
roles: [
{ role: "Sales", db: "test" },
{ role: "Operations", db: "test" },
{ role: "read", db: "test" }
]
} )
Create the collection创建集合
Run:运行:
db.budget.insertMany( [
{
_id: 0,
allowedRoles: [ "Marketing" ],
comment: "For marketing team",
yearlyBudget: 15000
},
{
_id: 1,
allowedRoles: [ "Sales" ],
comment: "For sales team",
yearlyBudget: 17000,
salesEventsBudget: 1000
},
{
_id: 2,
allowedRoles: [ "Operations" ],
comment: "For operations team",
yearlyBudget: 19000,
cloudBudget: 12000
},
{
_id: 3,
allowedRoles: [ "Development" ],
comment: "For development team",
yearlyBudget: 27000
}
] )
Perform the following steps to create a view and retrieve the documents accessible to 执行以下步骤以创建视图并检索John
:John
可访问的文档:
Create the view创建视图
To use a system variable, add 要使用系统变量,请在变量名的开头添加$$
to the start of the variable name. $$
。Specify the 将USER_ROLES
system variable as $$USER_ROLES
.USER_ROLES
系统变量指定为$$USER_ROLES
。
Run:运行:
db.createView(
"budgetView", "budget",
[ {
$match: {
$expr: {
$not: {
$eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ]
}
}
}
} ]
)
If you cannot create the view, ensure you log in as a user with the privilege to create a view.如果无法创建视图,请确保以具有创建视图权限的用户身份登录。
The previous example returns the documents from the 上一个示例返回budget
collection that match at least one of the roles that the user who runs the example has. budget
集合中与运行该示例的用户所具有的至少一个角色相匹配的文档。To do that, the example uses 为此,该示例使用$setIntersection
to return documents where the intersection between the budget
document allowedRoles
field and the set of user roles from $$USER_ROLES
is not empty.$setIntersection
返回budget
文档allowedRoles
字段和$$USER_ROLES
中的用户角色集之间的交集不为空的文档。
Examine the documents检查文件
John
has the Marketing
, Operations
, and Development
roles, and sees these documents:John
具有Marketing
、Operations
和Development
角色,并查看以下文档:
[
{
_id: 0,
allowedRoles: [ 'Marketing' ],
comment: 'For marketing team',
yearlyBudget: 15000
},
{
_id: 2,
allowedRoles: [ 'Operations' ],
comment: 'For operations team',
yearlyBudget: 19000,
cloudBudget: 12000
},
{
_id: 3,
allowedRoles: [ 'Development' ],
comment: 'For development team',
yearlyBudget: 27000
}
]
Perform the following steps to retrieve the documents accessible to Jane:执行以下步骤以检索Jane可访问的文档:
Examine the documents检查文件
Jane
has the Sales
and Operations
roles, and sees these documents:Jane
具有Sales
和Operations
角色,并查看以下文档:
[
{
_id: 1,
allowedRoles: [ 'Sales' ],
comment: 'For sales team',
yearlyBudget: 17000,
salesEventsBudget: 1000
},
{
_id: 2,
allowedRoles: [ 'Operations' ],
comment: 'For operations team',
yearlyBudget: 19000,
cloudBudget: 12000
}
]
On a sharded cluster, a query can be run on a shard by another server node on behalf of the user. 在分片集群上,另一个服务器节点可以代表用户在分片上运行查询。In those queries, 在这些查询中,USER_ROLES
is still populated with the roles for the user.USER_ROLES
仍然填充有用户的角色。
Roles with the Same Name in Multiple Databases多个数据库中具有相同名称的角色
Multiple databases can have roles with the same name. 多个数据库可以具有具有相同名称的角色。If you create a view and reference a specific role in the view, you should either specify both the 如果创建视图并引用视图中的特定角色,则应同时指定db
database name field and the role
field, or specify the _id
field that contains the database name and the role.db
数据库名称字段和role
字段,或者指定包含数据库名称和角色的_id
字段。
The following example returns the roles assigned to 以下示例返回分配给Jane的角色,Jane
, who has roles with different names. Jane
拥有不同名称的角色。The example returns the 此示例返回_id
, role
, and db
database name:_id
、role
和db
名称:
Examine the documents检查文件
Example output, which shows the 示例输出,显示_id
, role
, and db
database name in the myRoles
array:myRoles
数组中的_id
、role
和db
数据库名称:
{
_id: 0,
myRoles: [
{ _id: 'test.Operations', role: 'Operations', db: 'test' },
{ _id: 'test.Sales', role: 'Sales', db: 'test' },
{ _id: 'test.read', role: 'read', db: 'test' }
]
}
Behavior行为
The following sections describe the behaviors of view creation and queries.以下部分介绍了视图创建和查询的行为。
Aggregation Optimizations聚合优化
When you query a view:查询视图时:
Queryfilter
,projection
,sort
,skip
,limit
, and other operations fordb.collection.find()
are converted to the equivalent aggregation pipeline stages.db.collection.find()
的查询filter
、projection
、sort
、skip
、limit
和其他操作将转换为等效的聚合管道阶段。MongoDB appends the client query to the underlying pipeline and returns the results of that combined pipeline to the client.MongoDB将客户端查询附加到底层管道,并将组合管道的结果返回给客户端。MongoDB may apply aggregation pipeline optimizations to the combined pipeline.MongoDB可能会对合并后的管道进行聚合管道优化。The aggregation pipeline optimizer reshapes the view aggregation pipeline stages to improve performance.聚合管道优化器重新调整视图聚合管道阶段以提高性能。The optimization does not change the query results.优化不会更改查询结果。
Resource Locking资源锁定
db.createView()
obtains an exclusive lock on the specified collection or view for the duration of the operation. 在操作期间获取对指定集合或视图的独占锁定。All subsequent operations on the collection must wait until 集合上的所有后续操作都必须等待db.createView()
releases the lock. db.createView()
释放锁。db.createView()
typically holds this lock for a short time.通常将该锁保持短时间。
Creating a view requires obtaining an additional exclusive lock on the 创建视图需要对数据库中的system.views
collection in the database. system.views
集合获取额外的独占锁。This lock blocks creation or modification of views in the database until the command completes.此锁会阻止在数据库中创建或修改视图,直到命令完成。