Skip to content

Rest Doc for Full Text Search and withinPolygon #444

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
Sep 8, 2017
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
71 changes: 70 additions & 1 deletion _includes/rest/geopoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ result = json.loads(connection.getresponse().read())
print result
</code></pre>

This will return a list of results ordered by distance from 30.0 latitude and -20.0 longitude. The first result will be the nearest object. (Note that if an explicit `order` parameter is supplied, it will take precedence over the distance ordering.) For example, here are two results returned for the above query:
This will return a list of results ordered by distance from 30.0 latitude and -20.0 longitude. The first result will be the nearest object. (Note that if an explicit `order` parameter is supplied, it will take precedence over the distance ordering.) For example, here are two results returned for the above query:

<pre><code class="json">
{
Expand Down Expand Up @@ -208,6 +208,75 @@ result = json.loads(connection.getresponse().read())
print result
</code></pre>

* Starting with Parse-Server 2.5.0

It's also possible to query for the set of objects that are contained within or on the bounds of a polygon. `$polygon` allows for opened or closed paths, minimum of 3 `GeoPoint`'s.

<pre><code class="bash">
curl -X GET \
-H "X-Parse-Application-Id: ${APPLICATION_ID}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-G \
--data-urlencode 'where={
"location": {
"$geoWithin": {
"$polygon": [
{
"__type": "GeoPoint",
"latitude": 25.774,
"longitude": -80.190
},
{
"__type": "GeoPoint",
"latitude": 18.466,
"longitude": -66.118
},
{
"__type": "GeoPoint",
"latitude": 32.321,
"longitude": -64.757
}
]
}
}
}' \
https://api.parse.com/1/classes/PizzaPlaceObject
</code></pre>
<pre><code class="python">
import json,httplib,urllib
connection = httplib.HTTPSConnection('api.parse.com', 443)
params = urllib.urlencode({"where":json.dumps({
"location": {
"$geoWithin": {
"$polygon": [
{
"__type": "GeoPoint",
"latitude": 25.774,
"longitude": -80.190
},
{
"__type": "GeoPoint",
"latitude": 18.466,
"longitude": -66.118
},
{
"__type": "GeoPoint",
"latitude": 32.321,
"longitude": -64.757
}
]
}
}
})})
connection.connect()
connection.request('GET', '/1/classes/PizzaPlaceObject?%s' % params, '', {
"X-Parse-Application-Id": "${APPLICATION_ID}",
"X-Parse-REST-API-Key": "${REST_API_KEY}"
})
result = json.loads(connection.getresponse().read())
print result
</code></pre>

## Caveats

At the moment there are a couple of things to watch out for:
Expand Down
94 changes: 94 additions & 0 deletions _includes/rest/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ The values of the `where` parameter also support comparisons besides exact match
| $dontSelect | Requires that a key's value not match a value for a key in the result of a different query |
| $all | Contains all of the given values |
| $regex | Requires that a key's value match a regular expression |
| $text | Performs a full text search on indexed fields |

For example, to retrieve scores between 1000 and 3000, including the endpoints, we could issue:

Expand Down Expand Up @@ -556,6 +557,99 @@ 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.

* Starting with Parse-Server 2.5.0

For efficient search capabilities use the `$text` operator. By creating indexes on one or more columns your strings are turned into tokens for full text search functionality.

The format `{"$text": {"$search": {parameters}}}`

| Parameter | Use |
|--------------------------------------------------------------------------------------|
| $term | Specify a field to search (Required) |
| $language | Determines the list of stop words and the rules for tokenizer. |
| $caseSensitive | Enable or disable case sensitive search. |
| $diacriticSensitive | Enable or disable diacritic sensitive search |

Please refer to your database documentation on Full Text Search to setup your indexes, weights and limitations.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you put the links to those documentation for mongo 3.2 or 3.4 and PG?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done


<a href="https://docs.mongodb.com/v3.2/text-search/">Mongo 3.2 Full Text Search</a>

<a href="https://docs.mongodb.com/manual/reference/operator/query/text/">Mongo 3.4 Full Text Search</a>

<a href="https://www.postgresql.org/docs/9.5/static/textsearch.html">Postgres 9.5 Full Text Search</a>

Note: Postgres doesn't support `$caseSensitive` for Full Text Search, please use `$regex` above or create a lowercase column in your DB. Postgres supports `$diacriticSensitive: true` by default but `$diacriticSensitive: false` is not supported. To use false automatically, please install Postgres Unaccent Extension and update your text search configuration.

<pre><code class="bash">
# Finds strings that contains "Daddy"
curl -X GET \
-H "X-Parse-Application-Id: ${APPLICATION_ID}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-G \
--data-urlencode 'where={"name":{"$text":{"$search":{"$term":"Daddy"}}}}' \
https://api.parse.com/1/classes/BarbecueSauce
</code></pre>
<pre><code class="python">
# Finds barbecue sauces that contains "Daddy"
import json,httplib,urllib
connection = httplib.HTTPSConnection('api.parse.com', 443)
params = urllib.urlencode({"where":json.dumps({
"name": {
"$text": {
"$search": {
"$term": "Daddy"
}
}
}
})})
connection.connect()
connection.request('GET', '/1/classes/BarbecueSauce?%s' % params, '', {
"X-Parse-Application-Id": "${APPLICATION_ID}",
"X-Parse-REST-API-Key": "${REST_API_KEY}"
})
result = json.loads(connection.getresponse().read())
print result
</code></pre>

`$text` allows for sorting by `$score`. The text score signifies how well the string matched the search term(s) based on weights.

<pre><code class="bash">
# Finds strings that contains "Daddy" ordered by relevance
curl -X GET \
-H "X-Parse-Application-Id: ${APPLICATION_ID}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-G \
--data-urlencode 'where={"name":{"$text":{"$search":{"$term":"Daddy"}}}}' \
--data-urlencode 'order="$score"' \
--data-urlencode 'key="$score"' \
https://api.parse.com/1/classes/BarbecueSauce
</code></pre>
<pre><code class="python">
# Finds string that contains "Daddy" ordered by relevance
import json,httplib,urllib
connection = httplib.HTTPSConnection('api.parse.com', 443)
params = urllib.urlencode({"where":json.dumps({
"name": {
"$text": {
"$search": {
"$term": "Daddy"
}
}
}
}),
"order":"$score",
"keys":"$score",
})
connection.connect()
connection.request('GET', '/1/classes/BarbecueSauce?%s' % params, '', {
"X-Parse-Application-Id": "${APPLICATION_ID}",
"X-Parse-REST-API-Key": "${REST_API_KEY}"
})
result = json.loads(connection.getresponse().read())
print result
</code></pre>

Note: Both keys and order are required to sort by `$score`. You have to manually set weights on Postgres to use `$score`.

## Relational Queries

Expand Down