Skip to content

Commit

Permalink
Merge branch '5.10' into gh-9096
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Jun 15, 2020
2 parents 6bccb96 + 24f6a29 commit 6bd202e
Show file tree
Hide file tree
Showing 48 changed files with 954 additions and 589 deletions.
6 changes: 4 additions & 2 deletions docs/guide.pug
Expand Up @@ -81,8 +81,10 @@ block content

Keys may also be assigned nested objects containing further key/type definitions
like the `meta` property above. This will happen whenever a key's value is a POJO
that lacks a bona-fide `type` property. In these cases, only the leaves in a tree
are given actual paths in the schema (like `meta.votes` and `meta.favs` above),
that doesn't have a `type` property.

In these cases, Mongoose only creates actual schema paths for leaves
in the tree. (like `meta.votes` and `meta.favs` above),
and the branches do not have actual paths. A side-effect of this is that `meta`
above cannot have its own validation. If validation is needed up the tree, a path
needs to be created up the tree - see the [Subdocuments](./subdocs.html) section
Expand Down
16 changes: 8 additions & 8 deletions docs/index.pug
Expand Up @@ -31,7 +31,7 @@ block content

```javascript
// getting-started.js
var mongoose = require('mongoose');
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
```

Expand All @@ -40,7 +40,7 @@ block content
error occurs:

```javascript
var db = mongoose.connection;
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
// we're connected!
Expand All @@ -54,23 +54,23 @@ block content
Let's get a reference to it and define our kittens.

```javascript
var kittySchema = new mongoose.Schema({
const kittySchema = new mongoose.Schema({
name: String
});
```

So far so good. We've got a schema with one property, `name`, which will be a `String`. The next step is compiling our schema into a [Model](/docs/models.html).

```javascript
var Kitten = mongoose.model('Kitten', kittySchema);
const Kitten = mongoose.model('Kitten', kittySchema);
```

A model is a class with which we construct documents.
In this case, each document will be a kitten with properties and behaviors as declared in our schema.
Let's create a kitten document representing the little guy we just met on the sidewalk outside:

```javascript
var silence = new Kitten({ name: 'Silence' });
const silence = new Kitten({ name: 'Silence' });
console.log(silence.name); // 'Silence'
```

Expand All @@ -80,20 +80,20 @@ block content
```javascript
// NOTE: methods must be added to the schema before compiling it with mongoose.model()
kittySchema.methods.speak = function () {
var greeting = this.name
const greeting = this.name
? "Meow name is " + this.name
: "I don't have a name";
console.log(greeting);
}

var Kitten = mongoose.model('Kitten', kittySchema);
const Kitten = mongoose.model('Kitten', kittySchema);
```

Functions added to the `methods` property of a schema get compiled into
the `Model` prototype and exposed on each document instance:

```javascript
var fluffy = new Kitten({ name: 'fluffy' });
const fluffy = new Kitten({ name: 'fluffy' });
fluffy.speak(); // "Meow name is fluffy"
```

Expand Down
13 changes: 11 additions & 2 deletions docs/jest.pug
Expand Up @@ -23,10 +23,11 @@ block content
</div>

Jest is a client-side JavaScript testing library developed by Facebook.
It was one of the libraries affected by [Facebook's licensing scandal in 2017](https://www.theregister.co.uk/2017/09/22/facebook_will_free_react_other_code_from_unloved_license/).
Because Jest is designed primarily for testing React applications, using
it to test Node.js server-side applications comes with a lot of caveats.
We strongly recommend using [Mocha](http://npmjs.com/package/mocha) instead.
We strongly advise against using Jest for testing any Node.js apps unless
you are an expert developer with an intimate knowledge of Jest.

If you choose to delve into dangerous waters and test Mongoose apps with
Jest, here's what you need to know:

Expand Down Expand Up @@ -87,6 +88,14 @@ block content
sinon.stub(time, 'setTimeout');
```

## `globalSetup` and `globalTeardown`

Do **not** use `globalSetup` to call `mongoose.connect()` or
`mongoose.createConnection()`. Jest runs `globalSetup` in
a [separate environment](https://github.com/facebook/jest/issues/7184),
so you cannot use any connections you create in `globalSetup`
in your tests.

## Further Reading

Want to learn more about testing Mongoose apps? The
Expand Down
2 changes: 1 addition & 1 deletion docs/models.pug
Expand Up @@ -52,7 +52,7 @@ block content
```
:markdown
The first argument is the _singular_ name of the collection your model is
for. ** Mongoose automatically looks for the plural, lowercased version of your model name. **
for. **Mongoose automatically looks for the plural, lowercased version of your model name.**
Thus, for the example above, the model Tank is for the **tanks** collection
in the database.

Expand Down
23 changes: 23 additions & 0 deletions docs/schematypes.pug
Expand Up @@ -81,6 +81,7 @@ block content
- [Array](#arrays)
- [Decimal128](./api.html#mongoose_Mongoose-Decimal128)
- [Map](#maps)
- [Schema](#schemas)

<h4>Example</h4>

Expand Down Expand Up @@ -662,6 +663,28 @@ block content
schema.path('arr.0.url').get(v => `${root}${v}`);
```

<h3 id="schemas"><a href="#schemas">Schemas</a></h3>

To declare a path as another [schema](./guide.html#definition),
set `type` to the sub-schema's instance.

To set a default value based on the sub-schema's shape, simply set a default value,
and the value will be cast based on the sub-schema's definition before being set
during document creation.

```javascript
const subSchema = new mongoose.Schema({
// some schema definition here
});

const schema = new mongoose.Schema({
data: {
type: subSchema
default: {}
}
});
```

<h3 id="customtypes"><a href="#customtypes">Creating Custom Types</a></h3>

Mongoose can also be extended with [custom SchemaTypes](customschematypes.html). Search the
Expand Down
122 changes: 105 additions & 17 deletions docs/subdocs.pug
Expand Up @@ -44,6 +44,7 @@ block content
:markdown
<ul class="toc">
<li><a href="#what-is-a-subdocument-">What is a Subdocument?</a></li>
<li><a href="#subdocuments-versus-nested-paths">Subdocuments versus Nested Paths</a></li>
<li><a href="#finding-a-subdocument">Finding a Subdocument</a></li>
<li><a href="#adding-subdocs-to-arrays">Adding Subdocs to Arrays</a></li>
<li><a href="#removing-subdocs">Removing Subdocs</a></li>
Expand Down Expand Up @@ -110,8 +111,8 @@ block content
});

var parentSchema = new mongoose.Schema({
child: childSchema,
});
child: childSchema
});

parentSchema.pre('validate', function(next) {
console.log('1');
Expand All @@ -124,6 +125,59 @@ block content
});
```

### Subdocuments versus Nested Paths

In Mongoose, nested paths are subtly different from subdocuments.
For example, below are two schemas: one with `child` as a subdocument,
and one with `child` as a nested path.

```javascript
// Subdocument
const subdocumentSchema = new mongoose.Schema({
child: new mongoose.Schema({ name: String, age: Number })
});
const Subdoc = mongoose.model('Subdoc', subdocumentSchema);

// Nested path
const nestedSchema = new mongoose.Schema({
child: { name: String, age: Number }
});
const Nested = mongoose.model('Nested', nestedSchema);
```

These two schemas look similar, and the documents in MongoDB will
have the same structure with both schemas. But there are a few
Mongoose-specific differences:

First, instances of `Nested` never have `child === undefined`.
You can always set subproperties of `child`, even if you don't set
the `child` property. But instances of `Subdoc` can have `child === undefined`.

```javascript
const doc1 = new Subdoc({});
doc1.child === undefined; // true
doc1.child.name = 'test'; // Throws TypeError: cannot read property...

const doc2 = new Nested({});
doc2.child === undefined; // false
console.log(doc2.child); // Prints 'MongooseDocument { undefined }'
doc2.child.name = 'test'; // Works
```

Secondly, in Mongoose 5, [`Document#set()`](/docs/api/document.html#document_Document-set)
merges when you call it on a nested path, but overwrites when you call
it on a subdocument.

```javascript
const doc1 = new Subdoc({ child: { name: 'Luke', age: 19 } });
doc1.set({ child: { age: 21 } });
doc1.child; // { age: 21 }

const doc2 = new Nested({ child: { name: 'Luke', age: 19 } });
doc2.set({ child: { age: 21 } });
doc2.child; // { name: Luke, age: 21 }
```

h3#finding-a-subdocument Finding a Subdocument
:markdown
Each subdocument has an `_id` by default. Mongoose document arrays have a
Expand Down Expand Up @@ -222,8 +276,9 @@ block content

h4#altsyntaxarrays Alternate declaration syntax for arrays
:markdown
If you create a schema with an array of objects, mongoose will automatically
If you create a schema with an array of objects, Mongoose will automatically
convert the object to a schema for you:

```javascript
var parentSchema = new Schema({
children: [{ name: 'string' }]
Expand All @@ -234,25 +289,58 @@ block content
});
```

h4#altsyntaxsingle Alternate declaration syntax for single subdocuments
h4#altsyntaxsingle Alternate declaration syntax for single nested subdocuments
:markdown
Similarly, single subdocuments also have a shorthand whereby you can omit
wrapping the schema with an instance of Schema. However, for historical
reasons, this alternate declaration must be enabled via an option (either
on the parent schema instantiation or on the mongoose instance).
Unlike document arrays, Mongoose 5 does not convert an objects in schemas
into nested schemas. In the below example, `nested` is a _nested path_
rather than a subdocument.

```javascript
var parentSchema = new Schema({
child: { type: { name: 'string' } }
}, { typePojoToMixed: false });
// Equivalent
var parentSchema = new Schema({
child: new Schema({ name: 'string' })
const schema = new Schema({
nested: {
prop: String
}
});
// Not equivalent! Careful - a Mixed path is created instead!
var parentSchema = new Schema({
child: { type: { name: 'string' } }
```

This leads to some surprising behavior when you attempt to define a
nested path with validators or getters/setters.

```javascript
const schema = new Schema({
nested: {
// Do not do this! This makes `nested` a mixed path in Mongoose 5
type: { prop: String },
required: true
}
});

const schema = new Schema({
nested: {
// This works correctly
type: new Schema({ prop: String }),
required: true
}
});
```

Surprisingly, declaring `nested` with an object `type` makes `nested`
into a path of type [Mixed](/docs/schematypes.html#mixed). To instead
make Mongoose automatically convert `type: { prop: String }` into
`type: new Schema({ prop: String })`, set the `typePojoToMixed` option
to `false`.

```javascript
const schema = new Schema({
nested: {
// Because of `typePojoToMixed`, Mongoose knows to
// wrap `{ prop: String }` in a `new Schema()`.
type: { prop: String },
required: true
}
}, { typePojoToMixed: false });
```

h3#next Next Up
:markdown
Now that we've covered Subdocuments, let's take a look at
Expand Down
12 changes: 3 additions & 9 deletions index.pug
Expand Up @@ -235,18 +235,12 @@ html(lang='en')
<a href="https://proxybaylist.org/">
<img class="sponsor" src="https://images.opencollective.com/proxy-bay/e176fe4/avatar.png" style="height: 100px">
</a>
<a href="https://www.dcslsoftware.com/">
<img class="sponsor" src="https://images.opencollective.com/dcsl-software/a662911/logo.png" style="height: 100px">
</a>
<a href="https://ghostinspector.com/">
<img class="sponsor" src="https://images.opencollective.com/ghostinspector/51b7be8/logo.png" style="height: 100px">
</a>
<a href="https://moneypug.co.uk/">
<img class="sponsor" src="https://images.opencollective.com/moneypug/45f8d53/logo.png" style="height: 100px">
</a>
<a href="https://vpngorilla.com/">
<img class="sponsor" src="https://images.opencollective.com/vpngorilla-com/ae76cc5/logo.png" style="height: 100px">
</a>
<a href="https://medium.com/@niksundin/best-web-design-companies-1872e445775f">
<img class="sponsor" src="https://images.opencollective.com/top-web-design-agencies/d92d747/logo.png" style="height: 100px">
</a>
Expand Down Expand Up @@ -325,9 +319,6 @@ html(lang='en')
<a href="https://www.turtlebet.com/fi/kaikki-nettikasinot.html">
<img class="sponsor" src="https://images.opencollective.com/turtlebet-nettikasinot/4799a27/logo/256.png" style="height: 100px">
</a>
<a href="https://alltimelist.com/">
<img class="sponsor" src="https://images.opencollective.com/all-time-list/b04f3ee/logo/256.png" style="height: 100px">
</a>
<a href="https://casinomatcher.com/ca/">
<img class="sponsor" src="https://images.opencollective.com/casinomatcher-com/31fbd0d/logo/256.png" style="height: 100px">
</a>
Expand Down Expand Up @@ -370,6 +361,9 @@ html(lang='en')
<a href="https://aussiecasinohex.com/online-casinos/">
<img class="sponsor" src="https://images.opencollective.com/aussiecasinohex/923df37/logo/256.png" style="height: 100px">
</a>
<a href="https://www.japanesecasino.com/">
<img class="sponsor" src="https://images.opencollective.com/japanesecasino/b0ffe3c/logo/256.png" style="height: 100px">
</a>
</div>
</div>

Expand Down
26 changes: 26 additions & 0 deletions lib/aggregate.js
Expand Up @@ -909,6 +909,32 @@ Aggregate.prototype.facet = function(options) {
return this.append({ $facet: options });
};

/**
* Helper for [Atlas Text Search](https://docs.atlas.mongodb.com/reference/atlas-search/tutorial/)'s
* `$search` stage.
*
* ####Example:
*
* Model.aggregate().
* search({
* text: {
* query: 'baseball',
* path: 'plot'
* }
* });
*
* // Output: [{ plot: '...', title: '...' }]
*
* @param {Object} $search options
* @return {Aggregate} this
* @see $search https://docs.atlas.mongodb.com/reference/atlas-search/tutorial/
* @api public
*/

Aggregate.prototype.search = function(options) {
return this.append({ $search: options });
};

/**
* Returns the current pipeline
*
Expand Down

0 comments on commit 6bd202e

Please sign in to comment.