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 2 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 / on a polygon of `Parse.GeoPoint` (minimum 3 points):
Copy link
Contributor

Choose a reason for hiding this comment

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

can probably replace the / with 'or' just to be a bit more explicit.


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

You can query for whether an object `Parse.Polygon` contains a `Parse.GeoPoint`:
Copy link
Contributor

Choose a reason for hiding this comment

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

Stylistic

You can also query for whether...


<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
181 changes: 181 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

Use `fullText` for efficient search capabilities. Text indexes are automatically created for you. Your strings are turned into tokens for fast searching.
Copy link
Contributor

Choose a reason for hiding this comment

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

Stylistic

You can use fullText for efficient...


Copy link
Contributor

Choose a reason for hiding this comment

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

I would put the note regarding the 'cost' of full text search ops up here instead. That way it's a disclaimer of sorts as to what kind of impact this may have, before they start seeing any examples.

* Note: Full Text Search can be resource expensive. As with all indexes ensure you have enough RAM. Speed comes at a cost.
Copy link
Contributor

Choose a reason for hiding this comment

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

Stylistic


Requires Parse Server 2.5.0+
Copy link
Contributor

@montymxb montymxb Jan 18, 2018

Choose a reason for hiding this comment

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

I was wondering about these requirement labels, we should try to standardize them so they're not just dotted around. I think a solution could be to make sure this immediately follows the feature title. In this case ### Full Text Search. Also, and this is just a thought, but maybe we should italicize this entire requirement, just to emphasize it before the reader attempts to start implementing said feature.

Make sure to lead the requirement with * immediately following the introductory paragraph of the feature.


<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,151 @@ 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

* Note: MasterKey is Required. Parse Server 2.7.1+
Copy link
Contributor

Choose a reason for hiding this comment

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

Same thing here, we should move this statement directly below the title of Aggregate. Should make sure it's similar to the others as well. We can keep the master key requirement in there though, makes sense to have that as well.

Copy link
Contributor

@montymxb montymxb Jan 18, 2018

Choose a reason for hiding this comment

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

Also I'm not set in stone on this one. Using an * marks it with a blue + on the docs, and that might be good as is, but location should be standardized below the title.

Positioning is good here, but you could break up the masterKey & server requirement, with the server one first.


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">
Copy link
Contributor

Choose a reason for hiding this comment

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

I would add some descriptive text before this code block to detail what's in it, especially since it's only preceded by another block.

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">
Copy link
Contributor

Choose a reason for hiding this comment

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

Same thing here, something before it to describe and break it up would be nice.

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.

* Note: MasterKey is required. Parse Server 2.7.1+
Copy link
Contributor

@montymxb montymxb Jan 18, 2018

Choose a reason for hiding this comment

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

same here
Could break it up.


<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.

* `MasterKey` is required.
* Starting with Parse Server 2.7.1
Copy link
Contributor

@montymxb montymxb Jan 18, 2018

Choose a reason for hiding this comment

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

same here.
Positioning is pretty good here, and the parts are broken up. This how the others should be done as well. Could also stand to flip the order so the server requirement is prioritized before the master key.


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