User, Roles and Perm
## Sorting
-It is possible to sort the query result for one or more attributes. The query builder can be used to specify
+It is possible to sort the query result for one or more attributes. The query builder can be used to specify
which attributes shall be used for sorting. Let's sort our query result by name:
```js
DB.Todo.find()
@@ -283,8 +283,8 @@ DB.Todo.find()
.resultList(...)
```
-If you use more than one sort criterion, the order of the result reflects the order in which the sort methods were
-called. The following query will list all active tasks before the inactive ones and sort the tasks by their name in
+If you use more than one sort criterion, the order of the result reflects the order in which the sort methods were
+called. The following query will list all active tasks before the inactive ones and sort the tasks by their name in
ascending order.
```js
DB.Todo.find()
@@ -294,10 +294,10 @@ DB.Todo.find()
.resultList(...)
```
-When calling `descending('active')` before `ascending('name')` the result is sorted by name and
-then by active flag, which is only relevant for multiple todos having the same name.
+When calling `descending('active')` before `ascending('name')` the result is sorted by name and
+then by active flag, which is only relevant for multiple todos having the same name.
-You can also set the sort criteria with the MongoDB [orderby](http://docs.mongodb.org/manual/reference/operator/meta/orderby/)
+You can also set the sort criteria with the MongoDB [orderby](http://docs.mongodb.org/manual/reference/operator/meta/orderby/)
syntax by using the `sort()` method. An equivalent expression to the above is this:
```js
DB.Todo.find()
@@ -307,7 +307,7 @@ DB.Todo.find()
```
## Offset and Limit
-On larger data sets you usually don't want to load everything at once. Its often reasonable to instead page through the
+On larger data sets you usually don't want to load everything at once. Its often reasonable to instead page through the
query results. It is therefore possible to skip objects and limit the result size.
```js
var page = 3;
@@ -322,9 +322,9 @@ DB.Todo.find()
```
Note: An offset query on large result sets yields [poor query performance](http://use-the-index-luke
-.com/sql/partial-results/fetch-next-page). Instead, consider using a filter and sort criteria to navigate through
+.com/sql/partial-results/fetch-next-page). Instead, consider using a filter and sort criteria to navigate through
results.
-
+
For instance if you implement a simple pagination, you can sort by id and can get the data of the next
page by a simple greaterThen filter. As the id always has an index this results in good performance regardless of the
query result size.
@@ -342,8 +342,8 @@ DB.Todo.find()
})
```
-But often you want to sort your result by another attribute (e.g. `createdAt`). When you sort by an attribute which
-by itself is not unique you must combine it with a unique attribute (e.g. `id`).
+But often you want to sort your result by another attribute (e.g. `createdAt`). When you sort by an attribute which
+by itself is not unique you must combine it with a unique attribute (e.g. `id`).
```js
//initialize default values
@@ -351,33 +351,33 @@ var resultsPerPage = 30;
var lastObject = {id: '', createdAt: new Date(0)};
//later page through the pages by the following query
-var qb = DB.Todo.find();
+var qb = DB.Todo.find();
qb.or(qb.equal('createdAt', lastObject.createdAt).greaterThan('id', lastObject.id), qb.greaterThan('createdAt', lastObject.createdAt))
.ascending('createdAt')
.ascending('id')
.limit(resultsPerPage)
.resultList(function(result) {
//track last seen object
- lastObject = result[result.length - 1];
+ lastObject = result[result.length - 1];
console.log(result);
});
```
-*Explanation:* By combining the results of the query which fetches all remaining entities where the `createdAt` is equal to our last seen `createdAt`
-plus all ids which are greater than the last seen `id` we make our result unique when `createdAt` has the same value on
+*Explanation:* By combining the results of the query which fetches all remaining entities where the `createdAt` is equal to our last seen `createdAt`
+plus all ids which are greater than the last seen `id` we make our result unique when `createdAt` has the same value on
multiple entities. That guarantees a unique order for none unique attributes.
## Composing Filters by `and`, `or` and `nor`
-Filters are joined with `and` by default. In more complex cases you may want to formulate a query with one or more
-[and](http://docs.mongodb.org/manual/reference/operator/query/and/),
-[or](http://docs.mongodb.org/manual/reference/operator/query/or/) or
-[nor](http://docs.mongodb.org/manual/reference/operator/query/nor/) expressions.
-For such cases the initial `find()` call returns a
+Filters are joined with `and` by default. In more complex cases you may want to formulate a query with one or more
+[and](http://docs.mongodb.org/manual/reference/operator/query/and/),
+[or](http://docs.mongodb.org/manual/reference/operator/query/or/) or
+[nor](http://docs.mongodb.org/manual/reference/operator/query/nor/) expressions.
+For such cases the initial `find()` call returns a
[Query.Builder](https://www.baqend.com/js-sdk/latest/query.Builder.html) instance. The builder provides
additional methods to compose filter expressions.
-The following query finds all todos which the logged-in user is not currently working on and all todos which aren't
+The following query finds all todos which the logged-in user is not currently working on and all todos which aren't
done yet:
```js
var queryBuilder = DB.Todo.find();
@@ -393,20 +393,85 @@ queryBuilder.or(condition1, condition2)
.ascending('name')
.resultList(...)
```
+## Text search
+The text search provides a search mechanism with a wider approach than simple match-queries.
+On the one hand, results are ordered by their importance to the given search query.
+To achieve this, a score is computed for each matching object, which is composited by different factors, e.g.the frequency of your search terms in a field or given wheights for certain fields.
+On the other hand, there exists different techniques for finding objects, that are relevant to your query.
+To match inflected terms, words are reduced to their root form. For example "fishing", "fisher" and "fisher" would all be reduced to "fish" and match a query with "fishing", that also would reduced to "fish".
+Additionally the most common words of a certain language are filtered out from the search (In english this would be "the", "be", "to" etc.).
+
+If you want to use the full-text search, you have to create a text-index first.
+Navigate to the desired schema in the Baqend Dashboard and add the attributes, which should be regarded in a text search, to the text-index.
+
+You can specify different weights per attribute, to control the influence on the relevance score. If a term is present in certain field, a higher weight results in a higher score.
+
+It is highly recommended to set the right language for the text index in order to obtain the best results in a text search.
+
+
+To use the text search, simply add a `text` filter to your query builder.
+
+```js
+DB.Todo.find()
+ .text('My Todo')
+ .resultList(...)
+```
+
+
+You can combine the `text` filter with every other query builder function except sort filters.
+
+```js
+DB.Todo.find()
+ .text('My Todo')
+ .equal('active', true)
+ .limit(10)
+ .resultList(...)
+```
+
+Note: A query, wich contains the text
filter, sorts the results always by relevance. Adding an additional sort criteria has no effect on the ordering.
+
+
+
+All terms in the search string are combinded with a logical OR. To search for phrase, enlose the search terms in escaped double quotes
+```js
+DB.Todo.find()
+ .text('\"My Todo\"')
+ .resultList(...)
+```
+
+You can also negate words with a hyphen-minus prefix (-) to exclude objects which contain the negated word from the result set.
+
+The `text` filter has also some additional optional parameters, which correspond to the [MongoDB text operator](https://docs.mongodb.com/manual/reference/operator/query/text/).
+```python
+text(String searchTerm, String language, Boolean caseSensitive, Boolean diacriticSensitive)
+```
+
+With the `language` parameter you can determine the language of your query to improve the finding of relevant objects. If not specified or `null`, the default language of the underlying text-index is used.
+If you don't want the text search to use stemming or stop word removal, you can specify a language value of `none`.
+
+Setting the `caseSensitive` or `diacriticSensitive` parameter to 'true' will enable a case or diacritic sensitive search.
+
+Example for a case sensitive text search:
+```js
+DB.Todo.find()
+ .text('MY TODO', null, true)
+ .resultList(...)
+```
+
## Query Indexes
Indexes on fields that are frequently queried can massively impact the overall query performance. Therefore our Dashboard
-provides a very comfortable way to create custom indexes on fields. It is always an tradeof on which fields you should
-create an index. A good index should be created on fields that contains many distinct values. But to many indexes on the
+provides a very comfortable way to create custom indexes on fields. It is always an tradeof on which fields you should
+create an index. A good index should be created on fields that contains many distinct values. But to many indexes on the
same class can also reduce the write throughput. If you like to read more about indexes we currently use, visit the mongo
[indexes docs](https://docs.mongodb.org/manual/indexes/).
-To create an Index open the schema view of the class and use the *Index* or *Unique Index* button to create an index.
-Currently we support three types of indexes:
+To create an Index open the schema view of the class and use the *Index* or *Unique Index* button to create an index.
+Currently we support three types of indexes:
-**Index:** A simple index which contains a single field used to improve querys which filters the specified field.
+**Index:** A simple index which contains a single field used to improve querys which filters the specified field.
-**Unique Index:** A index that requires uniqueness of the field values. Inserting or updating objects that violates the
+**Unique Index:** A index that requires uniqueness of the field values. Inserting or updating objects that violates the
unique constraint will be rejected with an ObjectExists error.
**Geospatial Index:** This index can be created on GeoPoint fields and is required for `near` and `withinPolygon` query