Skip to content

Update JS Docs #497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions _includes/js/geopoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,38 @@ query.find({
});
</code></pre>

You can query for whether an object lies within or on a polygon of `Parse.GeoPoint` (minimum 3 points):

<pre><code class="javascript">
query.withinPolygon("location", [geoPoint1, geoPoint2, geoPoint3]);
query.find({
success: function(objectsWithGeoPointInPolygon) {
...
}
});
</code></pre>

You can also query for whether an object `Parse.Polygon` contains a `Parse.GeoPoint`:

<pre><code class="javascript">
const p1 = [[0,0], [0,1], [1,1], [1,0]];
const p2 = [[0,0], [0,2], [2,2], [2,0]];
const p3 = [[10,10], [10,15], [15,15], [15,10], [10,10]];

const polygon1 = new Parse.Polygon(p1);
const polygon2 = new Parse.Polygon(p2);
const polygon3 = new Parse.Polygon(p3);

const point = new Parse.GeoPoint(0.5, 0.5);
const query = new Parse.Query(TestObject);
query.polygonContains('polygon', point);
query.find({
success: function(results) {
// objects contains polygon1 and polygon2
}
});
</code></pre>

## Caveats

At the moment there are a couple of things to watch out for:
Expand Down
183 changes: 183 additions & 0 deletions _includes/js/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,39 @@ The above example will match any `BarbecueSauce` objects where the value in the

Queries that have regular expression constraints are very expensive, especially for classes with over 100,000 records. Parse restricts how many such operations can be run on a particular app at any given time.

### Full Text Search

You can use `fullText` for efficient search capabilities. Text indexes are automatically created for you. Your strings are turned into tokens for fast searching.

* Note: Full Text Search can be resource intensive. Ensure the cost of using indexes is worth the benefit, see [storage requirements & performance costs of text indexes.](https://docs.mongodb.com/manual/core/index-text/#storage-requirements-and-performance-costs).

* Parse Server 2.5.0+

<pre><code class="javascript">
var query = new Parse.Query(BarbecueSauce);
query.fullText('name', 'bbq');
</code></pre>

The above example will match any `BarbecueSauce` objects where the value in the "name" String key contains "bbq". For example, both "Big Daddy's BBQ", "Big Daddy's bbq" and "Big BBQ Daddy" will match.

<pre><code class="javascript">
// You can sort by weight / rank. ascending('') and select()
var query = new Parse.Query(BarbecueSauce);
query.fullText('name', 'bbq');
query.ascending('$score');
query.select('$score');
query.find()
.then(function(results) {
// results contains a weight / rank in result.get('score')
})
.catch(function(error) {
// There was an error.
});
</code></pre>



For Case or Diacritic Sensitive search, please use the [REST API](http://docs.parseplatform.org/rest/guide/#queries-on-string-values).

## Relational Queries

Expand Down Expand Up @@ -391,3 +424,153 @@ mainQuery.find()
// There was an error.
});
</code></pre>

## Aggregate

Queries can be made using aggregates, allowing you to retrieve objects over a set of input values. The results will not be `Parse.Object`s since you will be aggregating your own fields

* Parse Server 2.7.1+
* `MasterKey` is Required.

Aggregates use stages to filter results by piping results from one stage to the next.

You can create a pipeline using an Array or an Object.

The following example is a pipeline similar to `distinct` grouping by name field.

<pre><code class="javascript">
var pipelineObject = {
group: { objectId: '$name' }
};

var pipelineArray = [
{ group: { objectId: '$name' } }
];
</code></pre>

For a list of available operators please refer to [Mongo Aggregate Documentation](https://docs.mongodb.com/v3.2/reference/operator/aggregation/).

* Note: Most operations in Mongo Aggregate Documentation will work with Parse Server, but `_id` doesn't exist. Please replace with `objectId`.

Group pipeline is similar to `distinct`.

You can group by a field.

<pre><code class="javascript">
// score is the field. $ before score lets the database know this is a field
var pipeline = [
group: { objectId: '$score' }
];
var query = new Parse.Query("User");
query.aggregate(pipeline);
query.find()
.then(function(results) {
// results contains unique score values
})
.catch(function(error) {
// There was an error.
});
</code></pre>

You can apply collective calculations like $sum, $avg, $max, $min.

<pre><code class="javascript">
// total will be a newly created field to hold the sum of score field
var pipeline = [
group: { objectId: null, total: { $sum: '$score' } }
];
var query = new Parse.Query("User");
query.aggregate(pipeline);
query.find()
.then(function(results) {
// results contains sum of score field and stores it in results[0].total
})
.catch(function(error) {
// There was an error.
});
</code></pre>

Project pipeline is similar to `keys` or `select`, add or remove existing fields.

<pre><code class="javascript">
var pipeline = [
project: { name: 1 }
];
var query = new Parse.Query("User");
query.aggregate(pipeline);
query.find()
.then(function(results) {
// results contains only name field
})
.catch(function(error) {
// There was an error.
});
</code></pre>

Match pipeline is similar to `equalTo`.

<pre><code class="javascript">
var pipeline = [
{ match: { name: 'BBQ' } }
];
var query = new Parse.Query("User");
query.aggregate(pipeline);
query.find()
.then(function(results) {
// results contains name that matches 'BBQ'
})
.catch(function(error) {
// There was an error.
});
</code></pre>

You can match by comparison.

<pre><code class="javascript">
var pipeline = [
match: { score: { $gt: 15 } }
];
var query = new Parse.Query("User");
query.aggregate(pipeline);
query.find()
.then(function(results) {
// results contains score greater than 15
})
.catch(function(error) {
// There was an error.
});
</code></pre>

## Distinct

Queries can be made using distinct, allowing you find unique values for a specified field.

* Parse Server 2.7.1+
* `MasterKey` is required.

<pre><code class="javascript">
var query = new Parse.Query("User");
query.distinct("age");
query.find()
.then(function(results) {
// results contains unique age
})
.catch(function(error) {
// There was an error.
});
</code></pre>

You can also restrict results by using `equalTo`.

<pre><code class="javascript">
var query = new Parse.Query("User");
query.equalTo("name", "foo");
query.distinct("age");
query.find()
.then(function(results) {
// results contains unique age where name is foo
})
.catch(function(error) {
// There was an error.
});
</code></pre>
147 changes: 147 additions & 0 deletions _includes/js/schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Schema

Schema is the structure representing classes in your app. You can use the schema
of an app to verify operations in a unit test, generate test data, generate test
classes and then clean up after tests. The schema API can also be used to create
custom views of your data. We use the schema API to display column names and
types in the databrowser.

This API allows you to access the schemas of your app.

* Parse Server 2.7.1+
* `MasterKey` is required.

Schema will return an object similar to the following:

<pre><code class="javascript">
{
className: 'MyClass',
fields: {
// Default fields
ACL: {type: 'ACL'},
createdAt: {type: 'Date'},
updatedAt: {type: 'Date'},
objectId: {type: 'String'},
// Custom fields
aNumber: {type: 'Number'},
aString: {type: 'String'},
aBool: {type: 'Boolean'},
aDate: {type: 'Date'},
aObject: {type: 'Object'},
aArray: {type: 'Array'},
aGeoPoint: {type: 'GeoPoint'},
aPolygon: {type: 'Polygon'},
aFile: {type: 'File'}
},
classLevelPermissions: {
find: {
'*': true
},
create: {
'*': true
},
get: {
'*': true
},
update: {
'*': true
},
addField: {
'*': true
},
delete: {
'*': true
}
},
indexes: {
indexName: { aString: 1 },
}
}
</code></pre>

Direct manipulation of the classes that are on your server is possible through ParseSchema. Although fields and classes can be automatically generated (the latter assuming client class creation is enabled) ParseSchema gives you explicit control over these classes and their fields.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably would be good to add a little warning with this as well.

With great power comes great responsibility. Altering the schema directly should be done with care, you can't go back to retrieve data if you remove a field and it's associated values.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like


*With great power comes great responsibility. Altering the schema directly should be done with care, you can't go back to retrieve data if you remove a field and it's associated values.*

<pre><code class="javascript">
// create an instance to manage your class
const mySchema = new Parse.Schema('MyClass');

// gets the current schema data
mySchema.get();

// returns schema for all classes
Parse.Schema.all()

// add any # of fields, without having to create any objects
mySchema
.addString('stringField')
.addNumber('numberField')
.addBoolean('booleanField')
.addDate('dateField')
.addFile('fileField')
.addGeoPoint('geoPointField')
.addPolygon('polygonField')
.addArray('arrayField')
.addObject('objectField')
.addPointer('pointerField', '_User')
.addRelation('relationField', '_User');

// new types can be added as they are available
mySchema.addField('newField', 'ANewDataType')

// save/update this schema to persist your field changes
mySchema.save().then((result) => {
// returns save new schema
});
// or
mySchema.update().then((result) => {
// updates existing schema
});
</code></pre>

Assuming you want to remove a field you can simply call `deleteField` and `save/update` to clear it out.

<pre><code class="javascript">
mySchema.deleteField('stringField');
mySchema.save();
// or for an existing schema...
mySchema.update();
</code></pre>

## Indexes

Indexes support efficient execution of queries from the database. Keep in mind that the `masterKey` is required for these operations, so be sure it's set in your initialization code before you use this feature.

<pre><code class="javascript">
// To add an index, the field must exist before you create an index
mySchema.addString('stringField');
const index = {
stringField: 1
};
mySchema.addIndex('stringFieldIndex', index);
mySchema.save().then((result) => {
// returns schema including index stringFieldIndex and field stringField
});

// Delete an index
testSchema.deleteIndex('indexName');
mySchema.save().then((result) => {
// returns schema without indexName index
});

// If indexes exist, you can retrieve them
mySchema.get().then((result) => {
// result.indexes
});
</code></pre>

## Purge

All objects can be purged from a schema (class) via purge. But *be careful*! This can be considered an irreversible action. Only do this if you really need to delete all objects from a class, such as when you need to delete the class (as in the code example above).

<pre><code class="javascript">
// delete all objects in the schema
mySchema.purge();
</code></pre>

2 changes: 1 addition & 1 deletion _includes/rest/schemas.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ types in the databrowser.
This API allows you to access the schemas of your app.
Note: This API can be only accessed using the `master key`.

* Starting with Parse-Server 3.0 Index support added.
* Starting with Parse Server 2.7.1 Index support added.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't even realize the 3.0 thing there...nice catch


## Fetch the schema
To fetch the Schema for all the classes of your app, run:
Expand Down
1 change: 1 addition & 0 deletions js.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ sections:
- "js/analytics.md"
- "common/data.md"
- "common/relations.md"
- "js/schema.md"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're just adding schema.md you might want to drop schemas.md. In the php section I have it setup to reference schema.md already, might as well be consistent.

- "js/handling-errors.md"
- "common/security.md"
- "common/performance.md"
Expand Down