Appearance
集合
¥Collections
Meteor 将数据存储在集合中。要开始,请使用 new Mongo.Collection
声明一个集合。
¥Meteor stores data in collections. To get started, declare a collection with new Mongo.Collection
.
Mongo.Collection
Summary:
Constructor for a Collection
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
name | String | The name of the collection. If null, creates an unmanaged (unsynchronized) local collection. | Yes |
options | Object | No |
js
import { Mongo } from "meteor/mongo"";
const collection = new Mongo.Collection(
"name",
options, // this param is optional
);
调用此函数类似于在传统的以 ORM(对象关系映射器)为中心的框架中声明模型。它设置了一个集合(记录的存储空间或 "documents"),可用于存储特定类型的信息,如用户、帖子、分数、待办事项或任何对你的应用重要的信息。每个文档都是一个 EJSON 对象。它包含一个 _id
属性,该属性的值在集合中是唯一的,Meteor 将在你第一次创建文档时设置该属性。
¥Calling this function is analogous to declaring a model in a traditional ORM (Object-Relation Mapper)-centric framework. It sets up a collection (a storage space for records, or "documents") that can be used to store a particular type of information, like users, posts, scores, todo items, or whatever matters to your application. Each document is a EJSON object. It includes an _id
property whose value is unique in the collection, which Meteor will set when you first create the document.
js
// Common code on client and server declares a DDP-managed Mongo collection.
const Chatrooms = new Mongo.Collection("chatrooms");
const Messages = new Mongo.Collection("messages");
该函数返回一个对象,该对象具有 insert
集合中文档的方法、update
它们的属性、remove
它们的方法以及 find
集合中符合任意条件的文档的方法。这些方法的工作方式与流行的 Mongo 数据库 API 兼容。相同的数据库 API 适用于客户端和服务器(见下文)。
¥The function returns an object with methods to insert
documents in the collection, update
their properties, and remove
them, and to find
the documents in the collection that match arbitrary criteria. The way these methods work is compatible with the popular Mongo database API. The same database API works on both the client and the server (see below).
js
// Return an array of my messages.
const myMessages = await Messages.find({ userId: Meteor.userId() }).fetchAsync();
// Create a new message.
await Messages.insertAsync({ text: "Hello, world!" });
// Mark my first message as important.
await Messages.updateAsync(myMessages[0]._id, { $set: { important: true } });
如果你在创建集合时传递 name
,则你正在声明一个持久集合 - 存储在服务器上并可供所有用户查看的集合。客户端代码和服务器代码都可以使用相同的 API 访问相同的集合。
¥If you pass a name
when you create the collection, then you are declaring a persistent collection — one that is stored on the server and seen by all users. Client code and server code can both access the same collection using the same API.
具体来说,当你传递 name
时,会发生以下情况:
¥Specifically, when you pass a name
, here's what happens:
在服务器上(如果你未指定
connection
),则会在后端 Mongo 服务器上创建一个具有该名称的集合。当你在服务器上调用该集合上的方法时,它们会直接转换为正常的 Mongo 操作(在检查它们是否与你的 访问控制规则 匹配之后)。¥On the server (if you do not specify a
connection
), a collection with that name is created on a backend Mongo server. When you call methods on that collection on the server, they translate directly into normal Mongo operations (after checking that they match your access control rules).在客户端(如果指定了
connection
,则在服务器上)上,将创建一个 Minimongo 实例。Minimongo 本质上是纯 JavaScript 中 Mongo 的内存中非持久实现。它用作本地缓存,仅存储此客户端正在使用的数据库子集。这些集合上的查询(find
)直接从此缓存中提供,而无需与服务器通信。¥On the client (and on the server if you specify a
connection
), a Minimongo instance is created. Minimongo is essentially an in-memory, non-persistent implementation of Mongo in pure JavaScript. It serves as a local cache that stores just the subset of the database that this client is working with. Queries (find
) on these collections are served directly out of this cache, without talking to the server.当你在客户端(
insert
、update
、remove
)上写入数据库时,该命令会立即在本地执行,同时,它会被发送到服务器并在那里执行。这通过 stubs 发生,因为写入是作为方法实现的。¥When you write to the database on the client (
insert
,update
,remove
), the command is executed locally immediately, and, simultaneously, it's sent to the server and executed there too. This happens via stubs, because writes are implemented as methods.
当你在服务器上将具有指定
connection
的集合写入另一台服务器时,它会将相应的方法发送到另一台服务器并通过 DDP 从其接收更改的值。与客户端不同,它不会首先在本地执行写入。¥When, on the server, you write to a collection which has a specified
connection
to another server, it sends the corresponding method to the other server and receives the changed values back from it over DDP. Unlike on the client, it does not execute the write locally first.
危险
在 Meteor 3.x 及更高版本上,在服务器上使用 insert
、update
、upsert
、remove
、findOne
将抛出错误。改用 *Async
对应项。
¥On Meteor 3.x and later using insert
, update
, upsert
, remove
, findOne
on the server will throw and error. Use the *Async
counterparts instead.
例如,使用 collection.insertAsync(doc)
代替 collection.insert(doc)
。
¥For example, instead of collection.insert(doc)
, use collection.insertAsync(doc)
.
如果你将名称传递给仅限客户端的集合,它将不会与服务器同步,你需要使用底层发布接口 (added/changed/removed
) 填充集合 "manually"。有关更多信息,请参阅 added
。
¥If you pass a name to a client-only collection, it will not be synchronized with the server and you need to populate the collection "manually" using the low-level publication interface (added/changed/removed
). See added
for more information.
如果你将 null
作为 name
传递,则你正在创建一个本地集合。它未在任何地方同步;它只是一个支持 Mongo 样式 find
、insert
、update
和 remove
操作的本地暂存器。(在客户端和服务器上,此暂存器均使用 Minimongo 实现。)
¥If you pass null
as the name
, then you're creating a local collection. It's not synchronized anywhere; it's just a local scratchpad that supports Mongo-style find
, insert
, update
, and remove
operations. (On both the client and the server, this scratchpad is implemented using Minimongo.)
默认情况下,Meteor 会自动将你集合中的每个文档发布到每个连接的客户端。要关闭此行为,请在你的终端中删除 autopublish
包:
¥By default, Meteor automatically publishes every document in your collection to each connected client. To turn this behavior off, remove the autopublish
package, in your terminal:
bash
meteor remove autopublish
而是调用 Meteor.publish
来指定你的集合的哪些部分应该发布到哪个用户。
¥and instead call Meteor.publish
to specify which parts of your collection should be published to which users.
js
// client.js
// Create a collection called `Posts` and put a document in it. The document
// will be immediately visible in the local copy of the collection. It will be
// written to the server-side database a fraction of a second later, and a
// fraction of a second after that, it will be synchronized down to any other
// clients that are subscribed to a query that includes it (see
// `Meteor.subscribe` and `autopublish`).
const Posts = new Mongo.Collection("posts");
Posts.insert({ title: "Hello world", body: "First post" });
// Changes are visible immediately—no waiting for a round trip to the server.
assert(Posts.find().count() === 1);
// Create a temporary, local collection. It works just like any other collection
// but it doesn't send changes to the server, and it can't receive any data from
// subscriptions.
const Scratchpad = new Mongo.Collection();
for (let i = 0; i < 10; i += 1) {
Scratchpad.insert({ number: i * 2 });
}
assert(Scratchpad.find({ number: { $lt: 9 } }).count() === 5);
通常,你会将应用中的 Mongo.Collection
对象分配给全局变量。你只能为每个底层 Mongo 集合创建一个 Mongo.Collection
对象。
¥Generally, you'll assign Mongo.Collection
objects in your app to global variables. You can only create one Mongo.Collection
object for each underlying Mongo collection.
如果你为 Collection
或其任何检索方法指定了 transform
选项,则文档在返回或传递给回调之前会通过 transform
函数。这允许你添加方法或以其他方式从其数据库表示中修改集合的内容。你还可以在特定的 find
、findOne
、allow
或 deny
调用上指定 transform
。Transform 函数必须返回一个对象,并且它们不能更改文档的 _id
字段的值(尽管可以省略它)。
¥If you specify a transform
option to the Collection
or any of its retrieval methods, documents are passed through the transform
function before being returned or passed to callbacks. This allows you to add methods or otherwise modify the contents of your collection from their database representation. You can also specify transform
on a particular find
, findOne
, allow
, or deny
call. Transform functions must return an object and they may not change the value of the document's _id
field (though it's OK to leave it out).
js
// An animal class that takes a document in its constructor.
class Animal {
constructor(doc) {
_.extend(this, doc);
}
makeNoise() {
console.log(this.sound);
}
}
// Define a collection that uses `Animal` as its document.
const Animals = new Mongo.Collection("animals", {
transform: (doc) => new Animal(doc),
});
// Create an animal and call its `makeNoise` method.
Animals.insert({ name: "raptor", sound: "roar" });
Animals.findOne({ name: "raptor" }).makeNoise(); // Prints 'roar'
transform
函数不是被动调用的。如果你想向对象添加动态变化的属性,请使用在调用时计算值的函数来执行此操作,而不是通过在 transform
时计算属性来执行此操作。
¥transform
functions are not called reactively. If you want to add a dynamically changing attribute to an object, do it with a function that computes the value at the time it's called, not by computing the attribute at transform
time.
警告
在此版本中,Minimongo 有一些限制:
¥In this release, Minimongo has some limitations:
修饰符中的
$pull
只能接受某些类型的选择器。¥
$pull
in modifiers can only accept certain kinds of selectors.findAndModify
、聚合函数和 map/reduce 不受支持。¥
findAndModify
, aggregate functions, and map/reduce aren't supported.
所有这些都将在未来的版本中解决。有关完整的 Minimongo 发行说明,请参阅存储库中的 packages/minimongo/NOTES。
¥All of these will be addressed in a future release. For full Minimongo release notes, see packages/minimongo/NOTES in the repository.
警告
Minimongo 目前没有索引。这很少会成为问题,因为客户端拥有足够的数据以至于索引是值得的,这种情况并不常见。
¥Minimongo doesn't currently have indexes. It's rare for this to be an issue, since it's unusual for a client to have enough data that an index is worthwhile.
在 Meteor 指南中的 集合 文章中阅读有关集合及其使用方法的更多信息。
¥Read more about collections and how to use them in the Collections article in the Meteor Guide.
Collection.find
Summary:
Find the documents in a collection that match the selector.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | A query describing the documents to find | No |
options | Object | No |
js
// Collection is an instance of Mongo.Collection
/** @returns Mongo.Cursor */
const result = Collection.find(
MongoSelector, // this param is optional
options, // this param is optional
);
find
返回一个游标。它不会立即访问数据库或返回文档。Cursors 提供 fetch
来返回所有匹配的文档,map
和 forEach
来迭代所有匹配的文档,observeAsync
和 observeChangesAsync
来在匹配文档集发生变化时注册回调。Cursors 还实现了 ES2015 的 迭代协议。
¥find
returns a cursor. It does not immediately access the database or return documents. Cursors provide fetch
to return all matching documents, map
and forEach
to iterate over all matching documents, and observeAsync
and observeChangesAsync
to register callbacks when the set of matching documents changes. Cursors also implement ES2015's iteration protocols.
警告
集合游标不是查询快照。如果数据库在调用 Collection.find
和获取游标结果之间发生变化,或者在从游标获取结果时发生变化,这些更改可能会或可能不会出现在结果集中。
¥Collection cursors are not query snapshots. If the database changes between calling Collection.find
and fetching the results of the cursor, or while fetching results from the cursor, those changes may or may not appear in the result set.
Cursors 是一种反应性数据源。在客户端上,第一次在反应式计算(例如模板或 autorun
)中使用 fetch
、map
或 forEach
检索游标的文档时,Meteor 将在底层数据上注册依赖。对集合的任何更改(更改游标中的文档)都将触发重新计算。要禁用此行为,请将 {reactive: false}
作为选项传递给 find
。
¥Cursors are a reactive data source. On the client, the first time you retrieve a cursor's documents with fetch
, map
, or forEach
inside a reactive computation (eg, a template or autorun
), Meteor will register a dependency on the underlying data. Any change to the collection that changes the documents in a cursor will trigger a recomputation. To disable this behavior, pass {reactive: false}
as an option to find
.
请注意,当指定 fields
时,只有对包含字段的更改才会触发 observeAsync
、observeChangesAsync
中的回调以及使用此游标的反应式计算中的无效化。谨慎使用 fields
可以实现更细粒度的反应性,而无需依赖整个文档。
¥Note that when fields
are specified, only changes to the included fields will trigger callbacks in observeAsync
, observeChangesAsync
and invalidations in reactive computations using this cursor. Careful use of fields
allows for more fine-grained reactivity for computations that don't depend on an entire document.
在客户端,在页面加载和发布的数据从服务器到达之间会有一段时间,在此期间,你的客户端集合将为空。
¥On the client, there will be a period of time between when the page loads and when the published data arrives from the server during which your client-side collections will be empty.
Collection.findOne
Summary:
Finds the first document that matches the selector, as ordered by sort and skip options. Returns undefined
if no matching document is found.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | A query describing the documents to find | No |
options | Object | No |
js
// Collection is an instance of Mongo.Collection
/** @returns Object */
const result = Collection.findOne(
MongoSelector, // this param is optional
options, // this param is optional
);
相当于 find
(selector, options).
fetch
()[0]
和 options.limit = 1
。
¥Equivalent to find
(selector, options).
fetch
()[0]
with options.limit = 1
.
Collection.findOneAsync
Summary:
Finds the first document that matches the selector, as ordered by sort and skip options. Returns undefined
if no matching document is found.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | A query describing the documents to find | No |
options | Object | No |
js
// Collection is an instance of Mongo.Collection
/** @returns Object */
const result = Collection.findOneAsync(
MongoSelector, // this param is optional
options, // this param is optional
);
返回 Promise
的 findOne
的异步版本。
¥Async version of findOne
that return a Promise
.
Collection.countDocuments
Summary:
Gets the number of documents matching the filter. For a fast count of the total documents in a collection see estimatedDocumentCount
.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | A query describing the documents to count | No |
options | Object | All options are listed in MongoDB documentation. Please note that not all of them are available on the client. | No |
js
// Collection is an instance of Mongo.Collection
/** @returns Promise<number> */
const result = Collection.countDocuments(
MongoSelector, // this param is optional
options, // this param is optional
);
与 cursor.count
类似,但返回 Promise
。要获得更快的版本,请参阅 estimatedDocumentCount
。
¥Similar to cursor.count
, but returns a Promise
. For a faster version, see estimatedDocumentCount
.
Collection.estimatedDocumentCount
Summary:
Gets an estimate of the count of documents in a collection using collection metadata. For an exact count of the documents in a collection see countDocuments
.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
options | Object | All options are listed in MongoDB documentation. Please note that not all of them are available on the client. | No |
js
// Collection is an instance of Mongo.Collection
/** @returns Promise<number> */
const result = Collection.estimatedDocumentCount(
options
);
返回解析为游标结果集中的文档数量的 Promise
。计数是估计值,不保证准确。
¥Returns a Promise
that resolves to the number of documents in the cursor's result set. The count is an estimate and not guaranteed to be exact.
Collection.insert
Summary:
Insert a document in the collection. Returns a promise that will return the document's unique _id when solved.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
doc | Object | The document to insert. May not yet have an _id attribute, in which case Meteor will generate one for you. | Yes |
js
// Collection is an instance of Mongo.Collection
Collection.insert(
doc
);
将文档添加到集合。文档只是一个对象,其字段可以包含任何 EJSON 兼容数据类型的组合(数组、对象、数字、字符串、null
、true 和 false)。
¥Add a document to the collection. A document is just an object, and its fields can contain any combination of EJSON-compatible datatypes (arrays, objects, numbers, strings, null
, true, and false).
insert
将为你传递的对象生成一个唯一的 ID,将其插入数据库并返回该 ID。当从不受信任的客户端代码调用 insert
时,只有通过任何适用的 allow
和 deny
规则才会被允许。
¥insert
will generate a unique ID for the object you pass, insert it in the database, and return the ID. When insert
is called from untrusted client code, it will be allowed only if passes any applicable allow
and deny
rules.
在服务器上,应该使用 insertAsync
,它将返回一个带有对象 ID
的 promise。
¥On the server, it should be used insertAsync
that will return a promise with the ID
of your object.
在客户端,insert
永不阻塞。如果你不提供回调并且服务器上的插入失败,则 Meteor 将在控制台上记录警告。如果你提供回调,Meteor 将使用 error
和 result
参数调用该函数。在错误情况下,result
未定义。如果插入成功,error
未定义,result
是新的文档 ID。
¥On the client, insert
never blocks. If you do not provide a callback and the insert fails on the server, then Meteor will log a warning to the console. If you provide a callback, Meteor will call that function with error
and result
arguments. In an error case, result
is undefined. If the insert is successful, error
is undefined and result
is the new document ID.
示例:
¥Example:
js
const groceriesId = Lists.insert({ name: "Groceries" });
Items.insert({ list: groceriesId, name: "Watercress" });
Items.insert({ list: groceriesId, name: "Persimmons" });
Collection.insertAsync
Summary:
Insert a document in the collection. Returns its unique _id.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
doc | Object | The document to insert. May not yet have an _id attribute, in which case Meteor will generate one for you. | Yes |
js
// Collection is an instance of Mongo.Collection
/** @returns Promise */
const result = Collection.insertAsync(
doc
);
返回 Promise
的 insert
的异步版本。
¥Async version of insert
that return a Promise
.
Collection.update
Summary:
Asynchronously modifies one or more documents in the collection. Returns the number of matched documents.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | Specifies which documents to modify | Yes |
modifier | MongoModifier | Specifies how to modify the documents | Yes |
options | Object | No | |
callback | function | Optional. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second. | No |
js
// Collection is an instance of Mongo.Collection
Collection.update(
MongoSelector,
MongoModifier,
options, // this param is optional
() => {}, // this param is optional
);
根据 modifier
修改与 selector
匹配的文档(参见 修饰符文档)。
¥Modify documents that match selector
according to modifier
(see modifier documentation).
update
的行为取决于它是由受信任代码还是不受信任代码调用而不同。受信任的代码包括服务器代码和方法代码。不受信任的代码包括客户端代码,例如事件处理程序和浏览器的 JavaScript 控制台。
¥The behavior of update
differs depending on whether it is called by trusted or untrusted code. Trusted code includes server code and method code. Untrusted code includes client-side code such as event handlers and a browser's JavaScript console.
通过将
multi
设置为 true,受信任的代码可以一次修改多个文档,并且可以使用任意 Mongo 选择器 来查找要修改的文档。它绕过了allow
和deny
设置的任何访问控制规则。如果你不传递回调,则受影响的文档数量将从update
调用中返回。¥Trusted code can modify multiple documents at once by setting
multi
to true, and can use an arbitrary Mongo selector to find the documents to modify. It bypasses any access control rules set up byallow
anddeny
. The number of affected documents will be returned from theupdate
call if you don't pass a callback.不受信任的代码一次只能修改一个文档,由其
_id
指定。仅在检查任何适用的allow
和deny
规则后才允许修改。受影响的文档数量将返回到回调。不受信任的代码无法执行更新插入,除非在非安全模式下。¥Untrusted code can only modify a single document at once, specified by its
_id
. The modification is allowed only after checking any applicableallow
anddeny
rules. The number of affected documents will be returned to the callback. Untrusted code cannot perform upserts, except in insecure mode.
在服务器上,应该使用 updateAsync
。
¥On the server, it should be used updateAsync
.
在客户端,update
永不阻塞。如果你不提供回调并且服务器上的更新失败,则 Meteor 将在控制台上记录警告。如果你提供回调,如果出现错误,Meteor 将使用错误参数调用该函数,如果更新成功,则使用第二个参数指示受影响的文档数量。
¥On the client, update
never blocks. If you do not provide a callback and the update fails on the server, then Meteor will log a warning to the console. If you provide a callback, Meteor will call that function with an error argument if there was an error, or a second argument indicating the number of affected documents if the update was successful.
js
// Give the 'Winner' badge to each user with a score greater than 10. If they
// are logged in and their badge list is visible on the screen, it will update
// automatically as they watch.
Meteor.methods({
async declareWinners() {
await Players.updateAsync(
{ score: { $gt: 10 } },
{
$addToSet: { badges: "Winner" },
},
{ multi: true }
);
},
});
js
// When the 'give points' button in the admin dashboard is pressed, give 5
// points to the current player. The new score will be immediately visible on
// everyone's screens.
Template.adminDashboard.events({
"click .give-points"() {
Players.update(Session.get("currentPlayer"), {
$inc: { score: 5 },
});
},
});
你可以使用 update
通过将 upsert
选项设置为 true 来执行 Mongo upsert。你还可以使用 upsert
方法执行 upsert,除了受影响的文档数量外,还返回插入的文档的 _id
(如果有)。
¥You can use update
to perform a Mongo upsert by setting the upsert
option to true. You can also use the upsert
method to perform an upsert that returns the _id
of the document that was inserted (if there was one) in addition to the number of affected documents.
Collection.updateAsync
Summary:
Modify one or more documents in the collection. Returns the number of matched documents.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | Specifies which documents to modify | Yes |
modifier | MongoModifier | Specifies how to modify the documents | Yes |
options | Object | No |
js
// Collection is an instance of Mongo.Collection
/** @returns Promise */
const result = Collection.updateAsync(
MongoSelector,
MongoModifier,
options, // this param is optional
);
返回 Promise
的 update
的异步版本。
¥Async version of update
that return a Promise
.
Collection.upsert
Summary:
Asynchronously modifies one or more documents in the collection, or insert one if no matching documents were found. Returns an object with keys numberAffected
(the number of documents modified) and insertedId
(the unique _id of the document that was inserted, if any).
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | Specifies which documents to modify | Yes |
modifier | MongoModifier | Specifies how to modify the documents | Yes |
options | Object | No | |
callback | function | Optional. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second. | No |
js
// Collection is an instance of Mongo.Collection
Collection.upsert(
MongoSelector,
MongoModifier,
options, // this param is optional
() => {}, // this param is optional
);
根据 modifier
修改与 selector
匹配的文档,如果没有修改任何文档,则插入文档。upsert
与调用 update
并将 upsert
选项设置为 true 相同,只是 upsert
的返回值是一个包含键 numberAffected
和 insertedId
的对象。(update
仅返回数字受影响的文档。)
¥Modify documents that match selector
according to modifier
, or insert a document if no documents were modified. upsert
is the same as calling update
with the upsert
option set to true, except that the return value of upsert
is an object that contain the keys numberAffected
and insertedId
. (update
returns only the number of affected documents.)
Collection.upsertAsync
Summary:
Modify one or more documents in the collection, or insert one if no matching documents were found. Returns an object with keys numberAffected
(the number of documents modified) and insertedId
(the unique _id of the document that was inserted, if any).
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | Specifies which documents to modify | Yes |
modifier | MongoModifier | Specifies how to modify the documents | Yes |
options | Object | No |
js
// Collection is an instance of Mongo.Collection
/** @returns Promise */
const result = Collection.upsertAsync(
MongoSelector,
MongoModifier,
options, // this param is optional
);
返回 Promise
的 upsert
的异步版本。
¥Async version of upsert
that return a Promise
.
Collection.remove
Summary:
Remove documents from the collection
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | Specifies which documents to remove | Yes |
callback | function | Optional. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second. | No |
js
// Collection is an instance of Mongo.Collection
Collection.remove(
MongoSelector,
() => {}, // this param is optional
);
查找所有与 selector
匹配的文档并将其从集合中删除。
¥Find all of the documents that match selector
and delete them from the collection.
remove
的行为取决于它是由受信任代码还是不受信任代码调用而不同。受信任的代码包括服务器代码和方法代码。不受信任的代码包括客户端代码,例如事件处理程序和浏览器的 JavaScript 控制台。
¥The behavior of remove
differs depending on whether it is called by trusted or untrusted code. Trusted code includes server code and method code. Untrusted code includes client-side code such as event handlers and a browser's JavaScript console.
受信任的代码可以使用任意 Mongo 选择器 来查找要删除的文档,并且可以通过传递与多个文档匹配的选择器一次删除多个文档。它绕过了
allow
和deny
设置的任何访问控制规则。如果你不传递回调,则已从remove
返回已删除的文档数量。¥Trusted code can use an arbitrary Mongo selector to find the documents to remove, and can remove more than one document at once by passing a selector that matches multiple documents. It bypasses any access control rules set up by
allow
anddeny
. The number of removed documents will be returned fromremove
if you don't pass a callback.作为安全措施,如果省略
selector
(或为undefined
),则不会删除任何文档。如果你确实想从集合中删除所有文档,请将selector
设置为{}
。¥As a safety measure, if
selector
is omitted (or isundefined
), no documents will be removed. Setselector
to{}
if you really want to remove all documents from your collection.不受信任的代码一次只能删除一个文档,由其
_id
指定。仅在检查任何适用的allow
和deny
规则后,才会删除该文档。已删除的文档数量将返回到回调。¥Untrusted code can only remove a single document at a time, specified by its
_id
. The document is removed only after checking any applicableallow
anddeny
rules. The number of removed documents will be returned to the callback.
在服务器上,应该使用 removeAsync
。
¥On the server, it should be used removeAsync
.
在客户端,remove
永不阻塞。如果你不提供回调并且服务器上的删除失败,则 Meteor 将在控制台上记录警告。如果你提供回调,如果出现错误,Meteor 将使用错误参数调用该函数,如果删除成功,则使用第二个参数指示已删除的文档数量。
¥On the client, remove
never blocks. If you do not provide a callback and the remove fails on the server, then Meteor will log a warning to the console. If you provide a callback, Meteor will call that function with an error argument if there was an error, or a second argument indicating the number of removed documents if the remove was successful.
js
// When the server starts, clear the log and delete all players with a karma of
// less than -2.
Meteor.startup(async () => {
if (Meteor.isServer) {
await Logs.removeAsync({});
await Players.removeAsync({ karma: { $lt: -2 } });
}
});
js
// When the 'remove' button is clicked on a chat message, delete that message.
Template.chat.events({
"click .remove"() {
Messages.remove(this._id);
},
});
Collection.removeAsync
Summary:
Remove documents from the collection
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
selector | MongoSelector | Specifies which documents to remove | Yes |
js
// Collection is an instance of Mongo.Collection
/** @returns Promise */
const result = Collection.removeAsync(
MongoSelector
);
返回 Promise
的 remove
的异步版本。
¥Async version of remove
that return a Promise
.
Collection.createIndex server only
server only
Summary:
Asynchronously creates the specified index on the collection.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
index | Object | A document that contains the field and value pairs where the field is the index key and the value describes the type of index for that field. For an ascending index on a field, specify a value of | Yes |
options | Object | All options are listed in MongoDB documentation | No |
js
// Collection is an instance of Mongo.Collection
Collection.createIndex(
index,
options, // this param is optional
);
为了实现高效和高性能的查询,有时你需要定义除默认 _id
字段之外的索引。你应该向用于在集合中查找文档的字段(或字段组合)添加索引。这就是 createIndex
发挥作用的地方。它接受 2 个对象。首先是键和索引类型规范(应该使用哪个字段以及如何对它们进行索引),其次是选项,例如索引名称。有关索引如何工作的详细信息,请阅读 MongoDB 文档。
¥For efficient and performant queries you will sometimes need to define indexes other than the default _id
field. You should add indexes to fields (or combinations of fields) you use to lookup documents in a collection. This is where createIndex
comes into play. It takes in 2 objects. First is the key and index type specification (which field and how they should be indexed) and second are options like the index name. For details on how indexes work read the MongoDB documentation.
请注意,索引仅适用于服务器和 MongoDB 集合。它们目前尚未为 Minimongo 实现。
¥Note that indexes only apply to server and MongoDB collection. They are not implemented for Minimongo at this time.
在 Meteor 中定义 Players 集合的简单索引的示例:
¥Example defining a simple index on Players collection in Meteor:
js
Players.createIndex({ userId: 1 }, { name: "user reference on players" });
有时你或包可能会更改已经建立的索引。这可能会引发错误并阻止启动。如果你有能力重建索引或更改影响太多索引,你可以在 settings.json
中将 reCreateIndexOnOptionMismatch
设置为 true:
¥Sometimes you or a package might change an already established indexes. This might throw an error and prevent a startup. For cases where you can afford to re-build indexes or the change affect too many indexes you can set the reCreateIndexOnOptionMismatch
to true in your settings.json
:
json
{
"packages": {
"mongo": {
"reCreateIndexOnOptionMismatch": true
}
}
}
仅当你处理跨多个索引的更改并且无法手动修复它们并且你可以负担得起重建索引的费用时,你才应该使用此选项,因为这将破坏旧索引并创建一个新索引。请谨慎使用。
¥You should use this option only when you are dealing with a change across many indexes and it is not feasible to fix them manually and you can afford the re-building of the indexes as this will destroy the old index and create a new one. Use this carefully.
Collection.createIndexAsync server only
server only
Summary:
Asynchronously creates the specified index on the collection.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
index | Object | A document that contains the field and value pairs where the field is the index key and the value describes the type of index for that field. For an ascending index on a field, specify a value of | Yes |
options | Object | All options are listed in MongoDB documentation | No |
js
// Collection is an instance of Mongo.Collection
Collection.createIndexAsync(
index,
options, // this param is optional
);
返回 Promise
的 createIndex
的异步版本。
¥Async version of createIndex
that return a Promise
.
Collection.allow Server only
Server only
Summary:
Allow users to write directly to this collection from client code, subject to limitations you define.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
options | Object | Yes |
js
// Collection is an instance of Mongo.Collection
Collection.allow(
options
);
警告
虽然 allow
和 deny
使开始构建应用变得容易,但编写安全的 allow
和 deny
规则却比看起来要难。我们建议开发者避免使用 allow
和 deny
,并在他们准备好从应用中删除 insecure
模式时直接切换到自定义方法。有关更多详细信息,请参阅 Meteor 安全指南。
¥While allow
and deny
make it easy to get started building an app, it's harder than it seems to write secure allow
and deny
rules. We recommend that developers avoid allow
and deny
, and switch directly to custom methods once they are ready to remove insecure
mode from their app. See the Meteor Guide on security for more details.
当客户端在集合上调用 insert
/insertAsync
、update
/updateAsync
、remove
/removeAsync
时,服务器上会调用集合的 allow
和 deny
回调来确定是否应允许写入。如果至少一个 allow
回调允许写入,并且没有 deny
回调拒绝写入,则允许写入继续。
¥When a client calls insert
/insertAsync
, update
/updateAsync
, remove
/removeAsync
on a collection, the collection's allow
and deny
callbacks are called on the server to determine if the write should be allowed. If at least one allow
callback allows the write, and no deny
callbacks deny the write, then the write is allowed to proceed.
这些检查仅在客户端尝试直接写入数据库时运行,例如通过从事件处理程序内部调用 update
/updateAsync
。服务器代码是可信的,不受 allow
和 deny
限制。这包括使用 Meteor.call
调用的方法 — 它们应该进行自己的访问检查,而不是依赖 allow
和 deny
。
¥These checks are run only when a client tries to write to the database directly, for example by calling update
/updateAsync
from inside an event handler. Server code is trusted and isn't subject to allow
and deny
restrictions. That includes methods that are called with Meteor.call
— they are expected to do their own access checking rather than relying on allow
and deny
.
你可以根据需要多次调用 allow
,并且每次调用可以包含 insert
/insertAsync
、update
/updateAsync
和 remove
/removeAsync
函数的任意组合。如果函数认为应该允许该操作,则应返回 true
。否则,他们应该返回 false
,或者什么都不返回(undefined
)。在这种情况下,Meteor 将继续搜索集合中的任何其他 allow
规则。
¥You can call allow
as many times as you like, and each call can include any combination of insert
/insertAsync
, update
/updateAsync
, and remove
/removeAsync
functions. The functions should return true
if they think the operation should be allowed. Otherwise they should return false
, or nothing at all (undefined
). In that case Meteor will continue searching through any other allow
rules on the collection.
可用的回调是:
¥The available callbacks are:
回调
¥Callbacks
insert(userId, doc)
/insertAsync(userId, doc)
- 用户userId
想要将文档doc
插入到集合中。如果允许,则返回true
。¥
insert(userId, doc)
/insertAsync(userId, doc)
- The useruserId
wants to insert the documentdoc
into the collection. Returntrue
if this should be allowed.如果客户端明确设置了
_id
字段,或者存在活动的transform
,则doc
将包含_id
字段。你可以使用它来阻止用户指定任意_id
字段。¥
doc
will contain the_id
field if one was explicitly set by the client, or if there is an activetransform
. You can use this to prevent users from specifying arbitrary_id
fields.update(userId, doc, fieldNames, modifier)
/updateAsync(userId, doc, fieldNames, modifier)
- 用户userId
想要更新数据库中的文档doc
。(doc
是数据库中文档的当前版本,没有建议的更新。)返回true
以允许更改。¥
update(userId, doc, fieldNames, modifier)
/updateAsync(userId, doc, fieldNames, modifier)
- The useruserId
wants to update a documentdoc
in the database. (doc
is the current version of the document from the database, without the proposed update.) Returntrue
to permit the change.fieldNames
是客户端想要修改的doc
中的(顶层)字段的数组,例如['name', 'score']
。¥
fieldNames
is an array of the (top-level) fields indoc
that the client wants to modify, for example['name', 'score']
.modifier
是客户端想要执行的原始 Mongo 修饰符;例如,{ $set: { 'name.first': 'Alice' }, $inc: { score: 1 } }
。¥
modifier
is the raw Mongo modifier that the client wants to execute; for example,{ $set: { 'name.first': 'Alice' }, $inc: { score: 1 } }
.仅支持 Mongo 修饰符(类似
$set
和$push
的操作)。如果用户尝试替换整个文档而不是使用 $ 修饰符,则请求将被拒绝,而不检查allow
函数。¥Only Mongo modifiers are supported (operations like
$set
and$push
). If the user tries to replace the entire document rather than use $-modifiers, the request will be denied without checking theallow
functions.remove(userId, doc)
/removeAsync(userId, doc)
- 用户userId
想要从数据库中删除doc
。返回true
以允许此操作。¥
remove(userId, doc)
/removeAsync(userId, doc)
- the useruserId
wants to removedoc
from the database. Returntrue
to permit this.
当调用 update
/updateAsync
或 remove
/removeAsync
时,Meteor 默认会从数据库中获取整个文档 doc
。如果你有大型文档,你可能希望仅获取你的函数实际使用的字段。通过将 fetch
设置为要检索的字段名称数组来实现这一点。
¥When calling update
/updateAsync
or remove
/removeAsync
Meteor will by default fetch the entire document doc
from the database. If you have large documents you may wish to fetch only the fields that are actually used by your functions. Accomplish this by setting fetch
to an array of field names to retrieve.
示例:
¥Example:
js
// Create a collection where users can only modify documents that they own.
// Ownership is tracked by an `owner` field on each document. All documents must
// be owned by the user that created them and ownership can't be changed. Only a
// document's owner is allowed to delete it, and the `locked` attribute can be
// set on a document to prevent its accidental deletion.
const Posts = new Mongo.Collection("posts");
Posts.allow({
insert(userId, doc) {
// The user must be logged in and the document must be owned by the user.
return userId && doc.owner === userId;
},
update(userId, doc, fields, modifier) {
// Can only change your own documents.
return doc.owner === userId;
},
remove(userId, doc) {
// Can only remove your own documents.
return doc.owner === userId;
},
async insertAsync(userId, doc) {
// Any custom async validation is supported
const allowed = await allowInsertAsync(userId, doc);
return userId && allowed;
},
async updateAsync(userId, doc, fields, modifier) {
// Any custom async validation is supported
const allowed = await allowUpdateAsync(userId, doc);
return userId && allowed;
},
async removeAsync(userId, doc) {
// Any custom async validation is supported
const allowed = await allowRemoveAsync(userId, doc);
return userId && allowed;
},
fetch: ["owner"],
});
Posts.deny({
update(userId, doc, fields, modifier) {
// Can't change owners.
return _.contains(fields, "owner");
},
remove(userId, doc) {
// Can't remove locked documents.
return doc.locked;
},
async updateAsync(userId, doc, fields, modifier) {
// Any custom async validation is supported
const denied = await denyUpdateAsync(userId, doc);
return userId && denied;
},
async removeAsync(userId, doc) {
// Any custom async validation is supported
const denied = await denyRemoveAsync(userId, doc);
return userId && denied;
},
fetch: ["locked"], // No need to fetch `owner`
});
如果你从未在集合上设置任何 allow
规则,则所有客户端对该集合的写入都将被拒绝,并且只能从服务器端代码写入该集合。在这种情况下,你必须为允许客户端执行的每个可能的写入操作创建一个方法。然后,你将使用 Meteor.call
调用这些方法,而不是让客户端直接在集合上调用 insert
/insertAsync
、update
/updateAsync
和 remove
/removeAsync
。
¥If you never set up any allow
rules on a collection then all client writes to the collection will be denied, and it will only be possible to write to the collection from server-side code. In this case you will have to create a method for each possible write that clients are allowed to do. You'll then call these methods with Meteor.call
rather than having the clients call insert
/insertAsync
, update
/updateAsync
, and remove
/removeAsync
directly on the collection.
Meteor 还有一个特殊的 "不安全模式",用于快速制作新应用的原型。在非安全模式下,如果你没有在集合上设置任何 allow
或 deny
规则,则所有用户都对该集合具有完全的写访问权限。这是不安全模式的唯一效果。如果你在集合上调用 allow
或 deny
,甚至 Posts.allow({})
,那么对该集合的访问检查就像正常检查一样。新的 Meteor 项目默认以不安全模式启动。要关闭它,只需在你的终端中运行:
¥Meteor also has a special "insecure mode" for quickly prototyping new applications. In insecure mode, if you haven't set up any allow
or deny
rules on a collection, then all users have full write access to the collection. This is the only effect of insecure mode. If you call allow
or deny
at all on a collection, even Posts.allow({})
, then access is checked just like normal on that collection. New Meteor projects start in insecure mode by default. To turn it off just run in your terminal:
bash
meteor remove insecure
Collection.deny Server only
Server only
Summary:
Override allow
rules.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
options | Object | Yes |
js
// Collection is an instance of Mongo.Collection
Collection.deny(
options
);
警告
虽然 allow
和 deny
使开始构建应用变得容易,但编写安全的 allow
和 deny
规则却比看起来要难。我们建议开发者避免使用 allow
和 deny
,并在他们准备好从应用中删除 insecure
模式时直接切换到自定义方法。有关更多详细信息,请参阅 Meteor 安全指南。
¥While allow
and deny
make it easy to get started building an app, it's harder than it seems to write secure allow
and deny
rules. We recommend that developers avoid allow
and deny
, and switch directly to custom methods once they are ready to remove insecure
mode from their app. See the Meteor Guide on security for more details.
这就像 allow
一样工作,但它可以让你确保某些写入绝对被拒绝,即使有 allow
规则规定应该允许它们。
¥This works just like allow
, except it lets you make sure that certain writes are definitely denied, even if there is an allow
rule that says that they should be permitted.
当客户端尝试写入集合时,Meteor 服务器首先检查集合的 deny
规则。如果它们均未返回 true,则检查集合的 allow
规则。Meteor 仅当没有 deny
规则返回 true
并且至少有一个 allow
规则返回 true
时才允许写入。
¥When a client tries to write to a collection, the Meteor server first checks the collection's deny
rules. If none of them return true then it checks the collection's allow
rules. Meteor allows the write only if no deny
rules return true
and at least one allow
rule returns true
.
Collection.rawCollection Server only
Server only
Summary:
Returns the Collection
object corresponding to this collection from the npm mongodb
driver module which is wrapped by Mongo.Collection
.
js
// Collection is an instance of Mongo.Collection
Collection.rawCollection();
你在结果原始集合上调用的方法(如 update
或 insert
)返回 promise,可以在 Fiber 之外使用。
¥The methods (like update
or insert
) you call on the resulting raw collection return promises and can be used outside of a Fiber.
Collection.rawDatabase Server only
Server only
Summary:
Returns the Db
object corresponding to this collection's database connection from the npm mongodb
driver module which is wrapped by Mongo.Collection
.
js
// Collection is an instance of Mongo.Collection
Collection.rawDatabase();
光标 {#mongo_cursor}
¥Cursors
要创建游标,请使用 find
。要访问游标中的文档,请使用 forEach
、map
、fetch
、forEachAsync
、mapAsync
、fetchAsync
或 ES2015 的 迭代协议。
¥To create a cursor, use find
. To access the documents in a cursor, use forEach
, map
, fetch
, forEachAsync
, mapAsync
, fetchAsync
or ES2015's iteration protocols.
Cursor.forEach
Summary:
Call callback
once for each matching document, sequentially and
synchronously.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
callback | IterationCallback | Function to call. It will be called with three arguments: the document, a 0-based index, and cursor itself. | Yes |
thisArg | Any | An object which will be the value of | No |
js
// Cursor is an instance of Mongo.Cursor
Cursor.forEach(
IterationCallback,
any, // this param is optional
);
此接口与 Array.forEach 兼容。
¥This interface is compatible with Array.forEach.
当从反应式计算调用时,forEach
会在匹配的文档上注册依赖。
¥When called from a reactive computation, forEach
registers dependencies on the matching documents.
示例:
¥Examples:
js
// Print the titles of the five top-scoring posts.
const topPosts = Posts.find({}, { sort: { score: -1 }, limit: 5 });
let count = 0;
topPosts.forEach((post) => {
console.log(`Title of post ${count}: ${post.title}`);
count += 1;
});
Cursor.forEachAsync
Summary:
Call callback
once for each matching document, sequentially and
synchronously.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
callback | IterationCallback | Function to call. It will be called with three arguments: the document, a 0-based index, and cursor itself. | Yes |
thisArg | Any | An object which will be the value of | No |
js
// Cursor is an instance of Mongo.Cursor
/** @returns Promise */
const result = Cursor.forEachAsync(
IterationCallback,
any, // this param is optional
);
返回 Promise
的 forEach
的异步版本。
¥Async version of forEach
that return a Promise
.
与 forEach
相同的示例,但使用 forEachAsync
:
¥The same example as from forEach
but using forEachAsync
:
js
// Print the titles of the five top-scoring posts.
const topPosts = Posts.find({}, { sort: { score: -1 }, limit: 5 });
let count = 0;
await topPosts.forEachAsync((post) => {
console.log(`Title of post ${count}: ${post.title}`);
count += 1;
});
console.log("All done!"); // This will be printed after all the posts are printed.
Cursor.map
Summary:
Map callback over all matching documents. Returns an Array.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
callback | IterationCallback | Function to call. It will be called with three arguments: the document, a 0-based index, and cursor itself. | Yes |
thisArg | Any | An object which will be the value of | No |
js
// Cursor is an instance of Mongo.Cursor
Cursor.map(
IterationCallback,
any, // this param is optional
);
此接口与 Array.map 兼容。
¥This interface is compatible with Array.map.
当从反应式计算调用时,map
会在匹配的文档上注册依赖。
¥When called from a reactive computation, map
registers dependencies on the matching documents.
在服务器上,如果 callback
让步,则在第一个调用等待时可能会发生对 callback
的其他调用。如果需要严格顺序执行,请改用 forEach
。
¥On the server, if callback
yields, other calls to callback
may occur while the first call is waiting. If strict sequential execution is necessary, use forEach
instead.
Cursor.mapAsync
Summary:
Map callback over all matching documents. Returns an Array.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
callback | IterationCallback | Function to call. It will be called with three arguments: the document, a 0-based index, and cursor itself. | Yes |
thisArg | Any | An object which will be the value of | No |
js
// Cursor is an instance of Mongo.Cursor
/** @returns Promise */
const result = Cursor.mapAsync(
IterationCallback,
any, // this param is optional
);
返回 Promise
的 map
的异步版本。
¥Async version of map
that return a Promise
.
Cursor.fetch
Summary:
Return all matching documents as an Array.
js
// Cursor is an instance of Mongo.Cursor
/** @returns Array<Object> */
const result = Cursor.fetch();
当从反应式计算调用时,fetch
会在匹配的文档上注册依赖。
¥When called from a reactive computation, fetch
registers dependencies on the matching documents.
Cursor.fetchAsync
Summary:
Return all matching documents as an Array.
js
// Cursor is an instance of Mongo.Cursor
/** @returns Promise */
const result = Cursor.fetchAsync();
返回 Promise
的 fetch
的异步版本。
¥Async version of fetch
that return a Promise
.
Cursor.count
Summary:
Returns the number of documents that match a query. This method is
deprecated since MongoDB 4.0;
see Collection.countDocuments
and
Collection.estimatedDocumentCount
for a replacement.
js
// Cursor is an instance of Mongo.Cursor
/** @returns Number */
const result = Cursor.count();
与其他函数不同,count
仅注册对匹配文档数量的依赖。(仅更改或重新排序结果集中的文档的更新不会触发重新计算。)
¥Unlike the other functions, count
registers a dependency only on the number of matching documents. (Updates that just change or reorder the documents in the result set will not trigger a recomputation.)
Cursor.countAsync
Summary:
Returns the number of documents that match a query. This method is
deprecated since MongoDB 4.0;
see Collection.countDocuments
and
Collection.estimatedDocumentCount
for a replacement.
js
// Cursor is an instance of Mongo.Cursor
/** @returns Promise */
const result = Cursor.countAsync();
返回 Promise
的 count
的异步版本。
¥Async version of count
that return a Promise
.
Cursor.observeAsync
Summary:
Watch a query. Receive callbacks as the result set changes.
js
// Cursor is an instance of Mongo.Cursor
Cursor.observeAsync();
建立一个实时查询,当查询结果发生变化时调用回调。回调接收受影响的文档的全部内容,以及其旧内容(如果适用)。如果你只需要接收已更改的字段,请参阅 observeChangesAsync
。
¥Establishes a live query that invokes callbacks when the result of the query changes. The callbacks receive the entire contents of the document that was affected, as well as its old contents, if applicable. If you only need to receive the fields that changed, see observeChangesAsync
.
callbacks
可能具有以下函数作为属性:
¥callbacks
may have the following functions as properties:
回调
¥Callbacks
added(document)
或addedAt(document, atIndex, before)
新文档document
进入结果集。新文档出现在位置atIndex
。它位于_id
为before
的文档之前。如果新文档位于结果的末尾,则before
将为null
。¥
added(document)
oraddedAt(document, atIndex, before)
A new documentdocument
entered the result set. The new document appears at positionatIndex
. It is immediately before the document whose_id
isbefore
.before
will benull
if the new document is at the end of the results.changed(newDocument, oldDocument)
或changedAt(newDocument, oldDocument, atIndex)
文档的内容以前是oldDocument
,现在是newDocument
。更改的文档的位置是atIndex
。¥
changed(newDocument, oldDocument)
orchangedAt(newDocument, oldDocument, atIndex)
The contents of a document were previouslyoldDocument
and are nownewDocument
. The position of the changed document isatIndex
.removed(oldDocument)
或removedAt(oldDocument, atIndex)
文档oldDocument
不再位于结果集中。它曾经位于位置atIndex
。¥
removed(oldDocument)
orremovedAt(oldDocument, atIndex)
The documentoldDocument
is no longer in the result set. It used to be at positionatIndex
.movedTo(document, fromIndex, toIndex, before)
文档将其在结果集中的位置从fromIndex
更改为toIndex
(位于 ID 为before
的文档之前)。其当前内容是document
。¥
movedTo(document, fromIndex, toIndex, before)
A document changed its position in the result set, fromfromIndex
totoIndex
(which is before the document with idbefore
). Its current contents isdocument
.
当你不关心结果集中文档的顺序时,请使用 added
、changed
和 removed
。它们比 addedAt
、changedAt
和 removedAt
更高效。
¥Use added
, changed
, and removed
when you don't care about the order of the documents in the result set. They are more efficient than addedAt
, changedAt
, and removedAt
.
在 observeAsync
返回之前,added
(或 addedAt
)将被调用零次或多次以提供查询的初始结果。
¥Before observeAsync
returns, added
(or addedAt
) will be called zero or more times to deliver the initial results of the query.
observeAsync
返回实时查询句柄的 promise,该句柄是一个具有 stop
方法的对象。调用不带参数的 stop
以停止调用回调函数并拆除查询。查询将永远运行,直到你调用此查询。如果从 Tracker.autorun
计算中调用 observeAsync
,则在重新运行或停止计算时会自动停止。
¥observeAsync
returns a promise of the live query handle, which is an object with a stop
method. Call stop
with no arguments to stop calling the callback functions and tear down the query. The query will run forever until you call this. If observeAsync
is called from a Tracker.autorun
computation, it is automatically stopped when the computation is rerun or stopped.
提示
建议使用 observeAsync
以保持客户端和服务器中的代码同构。
¥observeAsync
is recommended to keep code isomorphism in the client and server.
observe
保持同步,以便于客户端处理程序管理。
¥observe
stays sync for easier client-side handler management.
(如果在将选项 reactive
设置为 false 的情况下创建游标,它将仅提供初始结果,并且不会调用任何进一步的回调;没有必要在句柄上调用 stop
。)
¥(If the cursor was created with the option reactive
set to false, it will only deliver the initial results and will not call any further callbacks; it is not necessary to call stop
on the handle.)
Cursor.observeChangesAsync
Summary:
Watch a query. Receive callbacks as the result set changes. Only the differences between the old and new documents are passed to the callbacks.
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
callbacks | Object | Functions to call to deliver the result set as it changes | Yes |
js
// Cursor is an instance of Mongo.Cursor
Cursor.observeChangesAsync(
callbacks
);
建立一个实时查询,当查询结果发生变化时调用回调。与 observeAsync
相比,observeChangesAsync
仅提供新旧结果集之间的差异,而不是更改的文档的全部内容。
¥Establishes a live query that invokes callbacks when the result of the query changes. In contrast to observeAsync
, observeChangesAsync
provides only the difference between the old and new result set, not the entire contents of the document that changed.
callbacks
可能具有以下函数作为属性:
¥callbacks
may have the following functions as properties:
回调
¥Callbacks
added(id, fields)
或addedBefore(id, fields, before)
新文档进入结果集。它指定了id
和fields
。fields
包含文档的所有字段(_id
字段除外)。新文档位于before
标识的文档之前,如果before
是null
,则位于文档末尾。¥
added(id, fields)
oraddedBefore(id, fields, before)
A new document entered the result set. It has theid
andfields
specified.fields
contains all fields of the document excluding the_id
field. The new document is before the document identified bybefore
, or at the end ifbefore
isnull
.changed(id, fields)
id
标识的文档更改了其内容。fields
包含已更改的字段及其新值。如果从文档中删除了字段,那么它将出现在fields
中,值为undefined
。¥
changed(id, fields)
The document identified byid
changed its contents.fields
contains the changed fields with their new values. If a field was removed from the document then it will be present infields
with a value ofundefined
.removed(id)
id
标识的文档不再位于结果集中。¥
removed(id)
The document identified byid
is no longer in the result set.movedBefore(id, before)
id
标识的文档更改了其在结果集中的位置,现在出现在before
标识的文档之前。¥
movedBefore(id, before)
The document identified byid
changed its position in the result set, and now appears before the document identified bybefore
.
如果你不使用 addedBefore
或 movedBefore
,observeChangesAsync
的效率会更高。
¥observeChangesAsync
is significantly more efficient if you do not use addedBefore
or movedBefore
.
在 observeChangesAsync
返回之前,added
(或 addedBefore
)将被调用零次或多次以提供查询的初始结果。
¥Before observeChangesAsync
returns, added
(or addedBefore
) will be called zero or more times to deliver the initial results of the query.
observeChangesAsync
返回实时查询句柄的 promise,该句柄是一个具有 stop
方法的对象。调用不带参数的 stop
以停止调用回调函数并拆除查询。查询将永远运行,直到你调用此查询。如果从 Tracker.autorun
计算中调用 observeChangesAsync
,则在重新运行或停止计算时会自动停止。
¥observeChangesAsync
returns a promise of the live query handle, which is an object with a stop
method. Call stop
with no arguments to stop calling the callback functions and tear down the query. The query will run forever until you call this. If observeChangesAsync
is called from a Tracker.autorun
computation, it is automatically stopped when the computation is rerun or stopped.
提示
建议使用 observeChangesAsync
以保持客户端和服务器中的代码同构。
¥observeChangesAsync
is recommended to keep code isomorphism in the client and server.
observeChanges
保持同步,以便于客户端处理程序管理。
¥observeChanges
stays sync for easier client-side handler management.
(如果在将选项 reactive
设置为 false 的情况下创建游标,它将仅提供初始结果,并且不会调用任何进一步的回调;没有必要在句柄上调用 stop
。)
¥(If the cursor was created with the option reactive
set to false, it will only deliver the initial results and will not call any further callbacks; it is not necessary to call stop
on the handle.)
与
observeAsync
不同,observeChangesAsync
不提供绝对位置信息(即atIndex
位置而不是before
位置)。这是为了提高效率。¥Unlike
observeAsync
,observeChangesAsync
does not provide absolute position information (that is,atIndex
positions rather thanbefore
positions.) This is for efficiency.
示例:
¥Example:
js
// Keep track of how many administrators are online.
let count = 0;
const cursor = Users.find({ admin: true, onlineNow: true });
const handle = await cursor.observeChangesAsync({
added(id, user) {
count += 1;
console.log(`${user.name} brings the total to ${count} admins.`);
},
removed() {
count -= 1;
console.log(`Lost one. We're now down to ${count} admins.`);
},
});
// After five seconds, stop keeping the count.
setTimeout(() => handle.stop(), 5000);
Mongo.ObjectID
Summary:
Create a Mongo-style ObjectID
. If you don't specify a hexString
, the ObjectID
will be generated randomly (not using MongoDB's ID construction rules).
Arguments:
Source codeName | Type | Description | Required |
---|---|---|---|
hexString | String | Optional. The 24-character hexadecimal contents of the ObjectID to create | No |
js
import { Mongo } from "meteor/mongo"";
const objectID = new Mongo.ObjectID(
"hexString"
);
Mongo.ObjectID
遵循与 Node MongoDB 驱动程序 ObjectID
类相同的 API。请注意,你必须使用 equals
方法(或 EJSON.equals
)来比较它们;===
操作符将不起作用。如果你正在编写需要处理可能是字符串或 ObjectID
的 _id
字段的通用代码,请使用 EJSON.equals
而不是 ===
来比较它们。
¥Mongo.ObjectID
follows the same API as the Node MongoDB driver ObjectID
class. Note that you must use the equals
method (or EJSON.equals
) to compare them; the ===
operator will not work. If you are writing generic code that needs to deal with _id
fields that may be either strings or ObjectID
s, use EJSON.equals
instead of ===
to compare them.
Meteor 创建的
ObjectID
值不会对其getTimestamp
方法产生有意义的答案,因为 Meteor 目前完全随机地构建它们。¥
ObjectID
values created by Meteor will not have meaningful answers to theirgetTimestamp
method, since Meteor currently constructs them fully randomly.
选择器
¥Selectors
最简单的选择器只是一个字符串或 Mongo.ObjectID
。这些选择器将文档与其 _id
字段中的值匹配。
¥The simplest selectors are just a string or Mongo.ObjectID
. These selectors match the document with that value in its _id
field.
选择器的一种稍微复杂一些的形式是一个对象,其中包含一组必须在文档中匹配的键:
¥A slightly more complex form of selector is an object containing a set of keys that must match in a document:
js
// Matches all documents where `deleted` is false.
{ deleted: false }
// Matches all documents where the `name` and `cognomen` are as given.
{ name: 'Rhialto', cognomen: 'the Marvelous' }
// Matches every document.
{}
但它们也可以包含更复杂的测试:
¥But they can also contain more complicated tests:
js
// Matches documents where `age` is greater than 18.
{
age: {
$gt: 18;
}
}
// Matches documents where `tags` is an array containing 'popular'.
{
tags: "popular";
}
// Matches documents where `fruit` is one of three possibilities.
{
fruit: {
$in: ["peach", "plum", "pear"];
}
}
查看 完整文档。
¥See the complete documentation.
修饰符
¥Modifiers
修饰符是一个对象,它描述如何通过更改文档的某些字段来更新文档。一些示例:
¥A modifier is an object that describes how to update a document in place by changing some of its fields. Some examples:
js
// Set the `admin` property on the document to true.
{ $set: { admin: true } }
// Add 2 to the `votes` property and add 'Traz' to the end of the `supporters`
// array.
{ $inc: { votes: 2 }, $push: { supporters: 'Traz' } }
但如果修饰符不包含任何 $ 运算符,则它将被解释为字面量文档,并完全替换数据库中先前的内容。(已验证的更新 目前不支持字面量文档修饰符。)
¥But if a modifier doesn't contain any $-operators, then it is instead interpreted as a literal document, and completely replaces whatever was previously in the database. (Literal document modifiers are not currently supported by validated updates.)
js
// Find the document with ID '123' and completely replace it.
Users.update({ _id: "123" }, { name: "Alice", friends: ["Bob"] });
查看 修饰符完整列表。
¥See the full list of modifiers.
排序说明符
¥Sort specifiers
可以使用你选择的几种语法指定排序:
¥Sorts may be specified using your choice of several syntaxes:
js
// All of these do the same thing (sort in ascending order by key `a`, breaking
// ties in descending order of key `b`).
[['a', 'asc'], ['b', 'desc']]
['a', ['b', 'desc']]
{ a: 1, b: -1 }
// Sorted by `createdAt` descending.
Users.find({}, { sort: { createdAt: -1 } });
// Sorted by `createdAt` descending and by `name` ascending.
Users.find({}, { sort: [['createdAt', 'desc'], ['name', 'asc']] });
最后一种形式仅在你的 JavaScript 实现保留对象中键的顺序时才有效。大多数情况下,大多数情况下都是这样,但这取决于你。
¥The last form will only work if your JavaScript implementation preserves the order of keys in objects. Most do, most of the time, but it's up to you to be sure.
对于本地集合,你可以传递一个比较器函数,该函数接收两个文档对象,如果第一个文档按顺序排在第一位,则返回 -1,如果第二个文档排在第一位,则返回 1,如果两个文档都不排在另一个前面,则返回 0。这是 MongoDB 的 Minimongo 扩展。
¥For local collections you can pass a comparator function which receives two document objects, and returns -1 if the first document comes first in order, 1 if the second document comes first, or 0 if neither document comes before the other. This is a Minimongo extension to MongoDB.
字段说明符
¥Field specifiers
查询可以指定要包含或排除在结果对象中的一组特定字段。
¥Queries can specify a particular set of fields to include or exclude from the result object.
要从结果对象中排除特定字段,字段说明符是一个字典,其键是字段名称,其值为 0
。包含所有未指定的字段。
¥To exclude specific fields from the result objects, the field specifier is a dictionary whose keys are field names and whose values are 0
. All unspecified fields are included.
js
Users.find({}, { fields: { password: 0, hash: 0 } });
要仅在结果文档中包含特定字段,请使用 1
作为值。_id
字段仍包含在结果中。
¥To include only specific fields in the result documents, use 1
as the value. The _id
field is still included in the result.
js
Users.find({}, { fields: { firstname: 1, lastname: 1 } });
除了一个例外,不能混合包含和排除样式:键必须全部为 1 或全部为 0。例外情况是,你可以在包含说明符中指定 _id: 0
,这也会将 _id
排除在结果对象之外。但是,此类字段说明符不能与从 发布功能 返回的 observeChangesAsync
、observeAsync
游标一起使用。它们可以与 fetch
、findOne
、forEach
和 map
一起使用。
¥With one exception, it is not possible to mix inclusion and exclusion styles: the keys must either be all 1 or all 0. The exception is that you may specify _id: 0
in an inclusion specifier, which will leave _id
out of the result object as well. However, such field specifiers can not be used with observeChangesAsync
, observeAsync
, cursors returned from a publish function. They may be used with fetch
, findOne
, forEach
, and map
.
$
和 $elemMatch
等 字段操作符 尚未在客户端提供。
¥Field operators such as $
and $elemMatch
are not available on the client side yet.
更高级的示例:
¥A more advanced example:
js
Users.insert({
alterEgos: [
{ name: "Kira", alliance: "murderer" },
{ name: "L", alliance: "police" },
],
name: "Yagami Light",
});
Users.findOne({}, { fields: { "alterEgos.name": 1, _id: 0 } });
// Returns { alterEgos: [{ name: 'Kira' }, { name: 'L' }] }
有关嵌套字段规则和数组行为的详细信息,请参阅 MongoDB 文档。
¥See the MongoDB docs for details of the nested field rules and array behavior.
连接到你的数据库 {#mongo_url}
¥Connecting to your database
当开发应用时,Meteor 会启动本地 MongoDB 实例并自动连接到它。在生产中,你必须在 标准 mongo 连接字符串格式 中指定指向数据库的 MONGO_URL
环境变量。
¥When developing your application, Meteor starts a local MongoDB instance and automatically connects to it. In production, you must specify a MONGO_URL
environment variable pointing at your database in the standard mongo connection string format.
如果你想连接到不同的 MongoDB 实例,你还可以在开发中设置
MONGO_URL
。¥You can also set
MONGO_URL
in development if you want to connect to a different MongoDB instance.
如果你想使用 oplog tailing 进行实时查询,你还应该设置 MONGO_OPLOG_URL
(通常你需要一个具有 oplog 访问权限的特殊用户,但细节可能因你托管 MongoDB 的方式而异。阅读更多 此处)。
¥If you want to use oplog tailing for livequeries, you should also set MONGO_OPLOG_URL
(generally you'll need a special user with oplog access, but the detail can differ depending on how you host your MongoDB. Read more here).
从 Meteor 1.4 开始,你必须确保在
METEOR_OPLOG_URL
上设置replicaSet
参数¥As of Meteor 1.4, you must ensure you set the
replicaSet
parameter on yourMETEOR_OPLOG_URL
MongoDB 连接选项 {#mongo_connection_options}
¥MongoDB connection options
MongoDB 提供许多连接选项,通常默认选项有效,但在某些情况下你可能需要传递其他选项。你可以通过两种方式执行此操作:
¥MongoDB provides many connection options, usually the default works but in some cases you may want to pass additional options. You can do it in two ways:
Meteor 设置 {#mongo_connection_options_settings}
¥Meteor settings
你可以使用 Meteor 设置文件在 packages
> mongo
内名为 options
的属性中设置选项,这些值将作为 MongoDB 在 connect 方法中的选项提供。
¥You can use your Meteor settings file to set the options in a property called options
inside packages
> mongo
, these values will be provided as options for MongoDB in the connect method.
此选项在 Meteor 1.10.2 中引入
¥this option was introduced in Meteor 1.10.2
例如,你可能想要为 TLS 连接指定证书(在此处查看选项),然后可以使用以下选项:
¥For example, you may want to specify a certificate for your TLS connection (see the options here) then you could use these options:
json
"packages": {
"mongo": {
"options": {
"tls": true,
"tlsCAFileAsset": "certificate.pem"
}
}
}
如果选项名称(键)以 Asset
结尾,Meteor 会将相对路径转换为绝对路径,为了使其正常工作,你需要将文件放在项目根目录中的 private
文件夹中。在示例中,Mongo 连接将收到以下内容:
¥Meteor will convert relative paths to absolute paths if the option name (key) ends with Asset
, for this to work properly you need to place the files in the private
folder in the root of your project. In the example Mongo connection would receive this:
json
"packages": {
"mongo": {
"options": {
"tls": true,
"tlsCAFile": "/absolute/path/certificate.pem"
}
}
}
看到最终选项名称(键)最终不包含 Asset
,正如 MongoDB 所期望的那样。
¥See that the final option name (key) does not contain Asset
in the end as expected by MongoDB.
在某些 MongoDB 主机提供商中,此配置是必需的,以避免此错误 MongoNetworkError: failed to connect to server [sg-meteorappdb-32194.servers.mongodirector.com:27017] on first connect [Error: self signed certificate
。
¥This configuration is necessary in some MongoDB host providers to avoid this error MongoNetworkError: failed to connect to server [sg-meteorappdb-32194.servers.mongodirector.com:27017] on first connect [Error: self signed certificate
.
避免此错误的另一种方法是使用此选项允许无效证书:
¥Another way to avoid this error is to allow invalid certificates with this option:
json
"packages": {
"mongo": {
"options": {
"tlsAllowInvalidCertificates": true
}
}
}
你可以传递任何 MongoDB 有效选项,这些只是使用证书配置的示例。
¥You can pass any MongoDB valid option, these are just examples using certificates configurations.
Mongo Oplog 选项
¥Mongo Oplog Options
Oplog 选项是在 Meteor 2.15.1 中引入的,如果你设置了
MONGO_OPLOG_URL
环境变量,Meteor 将使用 MongoDB 的 Oplog 通过你的订阅向你的用户显示高效、实时的更新。¥Oplog options were introduced in Meteor 2.15.1 If you set the
MONGO_OPLOG_URL
env var, Meteor will use MongoDB's Oplog to show efficient, real time updates to your users via your subscriptions.
由于 Meteor 的 Oplog 实现是在后台构建的,如果你有某些集合需要大量写入操作,这可能会导致你的 Meteor 应用服务器出现 CPU 峰值,即使你没有发布/订阅这些集合的任何数据/文档。有关此方面的更多信息,请查看 2016 年的这篇博文、2022 年的这个 github 讨论 或 2023 年的这个流星论坛帖子。
¥Due to how Meteor's Oplog implementation is built behind the scenes, if you have certain collections where you expect big amounts of write operations, this might lead to big CPU spikes on your meteor app server, even if you have no publications/subscriptions on any data/documents of these collections. For more information on this, please have a look into this blog post from 2016, this github discussion from 2022 or this meteor forums post from 2023.
为了解决这个问题,引入了 2 个 Oplog 设置来调整在 oplog 中监视或忽略哪些集合。
¥To solve this, 2 Oplog settings have been introduced to tweak, which collections are watched or ignored in the oplog.
排除:例如,要排除名为 products
和 prices
的两个集合中文档的所有更新/插入,你需要在 Meteor 设置文件中设置以下设置:
¥Exclusion: To exclude for example all updates/inserts of documents in the 2 collections called products
and prices
, you would need to set the following setting in your Meteor settings file:
json
"packages": {
"mongo": {
"oplogExcludeCollections": ["products", "prices"]
}
}
包含:反之亦然,如果你只想监视/包含 2 个集合 chats
和 messages
中文档更改的 oplog,你可以使用:
¥Inclusion: vice versa, if you only want to watch/include the oplog for changes on documents in the 2 collections chats
and messages
, you would use:
json
"packages": {
"mongo": {
"oplogIncludeCollections": ["chats", "messages"]
}
}
出于显而易见的原因,同时使用 oplogExcludeCollections
和 oplogIncludeCollections
是不可能的,并且会导致错误。
¥For obvious reasons, using both oplogExcludeCollections
and oplogIncludeCollections
at the same time is not possible and will result in an error.
Mongo.setConnectionOptions(options)
你还可以调用 Mongo.setConnectionOptions
来设置连接选项,但你需要在初始化使用 Mongo 连接的任何其他包之前调用它,因此你需要将此代码添加到包中并将其添加到其他包上方,例如 .meteor/packages
文件中的 accounts-base。
¥You can also call Mongo.setConnectionOptions
to set the connection options but you need to call it before any other package using Mongo connections is initialized so you need to add this code in a package and add it above the other packages, like accounts-base in your .meteor/packages
file.
此选项在 Meteor 1.4 中引入
¥this option was introduced in Meteor 1.4