# 查询（queries）

> 原文：[Queries](http://mongoosejs.com/docs/queries.html)\
> 翻译：小虾米（QQ:509129）

## Queries

可以通过[模型](http://mongoosejs.com/docs/models.html)的几个静态辅助方法检索文档。

任何涉及指定查询条件的[模型](http://mongoosejs.com/docs/api.html#model_Model)方法都可以执行两种方法：

当一个回调函数：

* 通过，操作将立即执行，结果传递给回调。
* 未通过，查询的一个实例被返回，它提供了一个特殊的查询生成器接口。

> 在mongoose 4，一个[查询](http://mongoosejs.com/docs/api.html#query-js)有一个 `.then()`功能，因此可以被用来作为一个承诺。

当执行一个查询回调函数，你指定一个JSON文档作为你的查询。JSON文档的语法是MongoDB的shell一样。

```javascript
var Person = mongoose.model('Person', yourSchema);

// find each person with a last name matching 'Ghost', selecting the `name` and `occupation` fields
Person.findOne({ 'name.last': 'Ghost' }, 'name occupation', function (err, person) {
  if (err) return handleError(err);
  console.log('%s %s is a %s.', person.name.first, person.name.last, person.occupation) // Space Ghost is a talk show host.
})
```

在这里，我们看到，查询立即执行，并将结果传递给我们的回调。所有在Mongoose的回调使用模式：`callback(error, result)`。如果执行查询时发生错误，则错误参数将包含一个错误文档，结果将是无效的。如果查询成功，错误参数将为空，结果将与查询的结果填充。

> 在Mongoose中任何一个回调传递给一个查询，回调如下模式`callback(error, results)`。什么样的结果是取决于操作：为 [findone()](http://mongoosejs.com/docs/api.html#model_Model.findOne) 它是一种单文档，[find() ](http://mongoosejs.com/docs/api.html#model_Model.find)一个文档列表，[count()](http://mongoosejs.com/docs/api.html#model_Model.count)文档数量，[update()](http://mongoosejs.com/docs/api.html#model_Model.update) 文件数量等影响，[API文档模型](http://mongoosejs.com/docs/api.html#model-js)提供更加详细的关于什么是传递给回调函数。

现在让我们看看在没有回调时发生了什么：

```javascript
// find each person with a last name matching 'Ghost'
var query = Person.findOne({ 'name.last': 'Ghost' });

// selecting the `name` and `occupation` fields
query.select('name occupation');

// execute the query at a later time
query.exec(function (err, person) {
  if (err) return handleError(err);
  console.log('%s %s is a %s.', person.name.first, person.name.last, person.occupation) // Space Ghost is a talk show host.
})
```

在上面的代码中，查询变量是类型[查询](http://mongoosejs.com/docs/api.html#query-js)。查询允许您建立一个查询使用链式语法，而不是指定一个JSON对象。下面的2个例子是等价的。

```javascript
// With a JSON doc
Person.
  find({
    occupation: /host/,
    'name.last': 'Ghost',
    age: { $gt: 17, $lt: 66 },
    likes: { $in: ['vaporizing', 'talking'] }
  }).
  limit(10).
  sort({ occupation: -1 }).
  select({ name: 1, occupation: 1 }).
  exec(callback);

// Using query builder
Person.
  find({ occupation: /host/ }).
  where('name.last').equals('Ghost').
  where('age').gt(17).lt(66).
  where('likes').in(['vaporizing', 'talking']).
  limit(10).
  sort('-occupation').
  select('name occupation').
  exec(callback);
```

一个完整的查询辅助功能列表可以在[API文档](http://mongoosejs.com/docs/api.html#query-js)中找到。

### 其他文档的参考资料

There are no joins in MongoDB but sometimes we still want references to documents in other collections. This is where [population](http://mongoosejs.com/docs/populate.html) comes in. Read more about how to include documents from other collections in your query results [here](http://mongoosejs.com/docs/api.html#query_Query-populate).

### Streaming

你可以从MongoDB查询结果。你需要调用[Query#cursor()](http://mongoosejs.com/docs/api.html#query_Query-stream)函数代替[Query#exec](http://mongoosejs.com/docs/api.html#query_Query-exec)返回一个 [QueryCursor](http://mongoosejs.com/docs/api.html#querycursor-js)实例。

```javascript
var cursor = Person.find({ occupation: /host/ }).cursor();
cursor.on('data', function(doc) {
  // Called once for every document
});
cursor.on('close', function() {
  // Called when done
});
```

### 下一步

既然我们已经掌握了查询，让我们看看[验证](http://mongoosejs.com/docs/validation.html)。
