# Querying

## Query Arguments

Objects can be queried using the available query arguments, allowing developers to easily search large amounts using the API.

Query arguments are applied in the following order: where, sort, skip, limit

| Name  | Description                                                                                                                                                                                                                      | Example                                                                                                               |
| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| where | Accepts A JSON object containing operators and expressions used to limit the search results.                                                                                                                                     | where={“$and”: \[{“created”: {“$gt”: “2015-01-01T00:00:00.000Z”}}, {“created”: {“$lt”: “2015-06-01T00:00:00.000Z”}}]} |
| sort  | Used to sort results, can be an indexed property name or a named grouping (when group is used). Also accepts a JSON object containing one or more properties, the values of which must be 1 for ascending and -1 for descending. | sort=posts or sort={“posts”: 1, “\_id”: 1}                                                                            |
| skip  | An integer representing the number of results to skip. Useful for paging where mapping or groupings have been applied, or where search the search criteria cannot be paged using unique fields.                                  | skip=100                                                                                                              |
| limit | An integer representing the number of results to return.                                                                                                                                                                         | limit=20                                                                                                              |

### Where

The `where` argument limits the resulting document list using search criteria applied against indexed properties.

```
?where={<query conditions>}
```

See Query Operators for more details and examples of available conditions.

#### Examples

For example, the following call finds all accounts where the last name starts with the letter s (case-insensitive) and sorts by last name, then by first name.Example

{% tabs %}
{% tab title="Example Request" %}

```javascript
GET /accounts?where={"name.last": {"$regex": "/^s/i"}}
```

{% endtab %}

{% tab title="Result" %}

```javascript
{
    "data": [
        {
            "_id": "5888b91d35f8c91536c6ddea",
            "access": 6,
            "c_enrollments": [],
            "c_study_groups": [],
            "created": "2017-01-25T14:41:33.297Z",
            "email": "john@medable.com",
            "favorite": false,
            "gender": "m",
            "inherited_roles": [
                "000000000000000000000007",
                "000000000000000000000006"
            ],
            "key": {
                "fingerprint": "8e53d430-e30c-11e6-aaeb-99172490c13b",
                "secret": "heBcf2Wgh6hjezADTAc88wHJNGcJgwUd"
            },
            "locale": "en_US",
            "locked": false,
            "mobile": "+12223334449",
            "name": {
                "first": "John",
                "last": "Silver"
            },
            "object": "account",
            "roles": [
                "000000000000000000000004"
            ],
            "shared": false,
            "state": "verified",
            "updated": "2017-01-25T14:42:54.970Z",
            "updater": {
                "_id": "5888b91d35f8c91536c6ddea",
                "object": "account",
                "path": "/accounts/5888b91d35f8c91536c6ddea"
            }
        }
    ],
    "hasMore": false,
    "object": "list"
}
```

{% endtab %}
{% endtabs %}

### Sort

Sorting can be applied to indexed properties, or to any named property when a grouping is applied. The value can be a single property name `sort=total`, or a JSON object containing\
one or more property names with either 1 (ascending) or -1 (descending) as the value.

```
?where={<query conditions>}&sort=<property>
```

Or when specifying the sort order:

```
?where={<query conditions>}&sort={<property>: <sort order>}
```

Or sorting by multiple properties:

```
?where={<query conditions>}&sort={<property1>: <sort order>, <property2>: <sort order>, ...}
```

#### Examples

The following shows an example of sorting a list of accounts by last name then by first name.

{% tabs %}
{% tab title="Example Request" %}

```
GET /accounts/?paths[]=name&sort={"name.last": 1, "name.first": 1}
```

{% endtab %}

{% tab title="Result" %}

```javascript
{                
    "data": [
        {
            "_id": "507f1f77bcf86cd799439011",
            "name": {
                "first": "John",
                "last": "Smith"
            },
            "object": "account"
        },
        {
            "_id": "55ff9db67a00a89c14aa31a6",
            "name": {
                "first": "Stan",
                "last": "Smith"
            },
            "object": "account"
        },
        {
            "_id": "507f191e810c19729de860ea",
            "name": {
                "first": "Jane",
                "last": "Svenson"
            },
            "object": "account"
        },                        
        ...  
  ],
  "hasMore": true,
  "object": "list"
}
```

{% endtab %}
{% endtabs %}

### Skip

The skip argument lets you specify a number of results to skip in your result set.

```
?where={<query conditions>}&skip=<positive integer>
```

#### Examples

For example, if you have a result set of 200, and you specify `skip=100`, you would receive results 101-200.skip

```javascript
GET /accounts/?paths[]=name&skip=2

{                
    "data": [
        {
            "_id": "507f191e810c19729de860ea",
            "name": {
                "first": "Jane",
                "last": "Svenson"
            },
            "object": "account"
        }                       
  ],
  "hasMore": false,
  "object": "list"
}

/* if the full result set was
[
  {
    "_id": "507f1f77bcf86cd799439011",
    "name": {
      "first": "John",
      "last": "Smith"
    },
    "object": "account"
  },
  {
    "_id": "55ff9db67a00a89c14aa31a6",
    "name": {
      "first": "Stan",
      "last": "Smith"
    },
    "object": "account"
  },
  {
    "_id": "507f191e810c19729de860ea",
    "name": {
      "first": "Jane",
      "last": "Svenson"
    },
    "object": "account"
  }                       
]
*/
```

{% hint style="info" %}
Limitations of paging with skip

Paging using `skip` should only be used for small result sets of a few hundred or less. For paging larger result sets, see Paging.
{% endhint %}

### Limit

The limit argument allows you to specify a number of results to return, e.g. `limit=2`. The default limit for an API request is 100. The max limit is 1000.

```
?where={<query conditions>}&limit=<positive integer>
```

If you are dealing with a result set larger than 1000, you should either narrow your result set with a more specific where clause or use pagination to page through your full result set.

#### Examples

```javascript
GET /accounts/?paths[]=name&limit=2

{                
    "data": [
        {
            "_id": "507f1f77bcf86cd799439011",
            "name": {
                "first": "John",
                "last": "Smith"
            },
            "object": "account"
        },
        {
            "_id": "55ff9db67a00a89c14aa31a6",
            "name": {
                "first": "Stan",
                "last": "Smith"
            },
            "object": "account"
        }
  ],
  "hasMore": true,
  "object": "list"
}
```

### Paging

Most API calls that result in a list response can be paged by using the `hasMore` property when it is `true`. Paging results can be accomplished using `limit` and `where` query arguments or a combination of `where`, `limit` and `skip` query arguments.

The recommended method for paging is using indexed, unique identifiers such as `_id`, sorting by the identifier and applying a where argument. For example:

```
?where={"_id": {"$gt": "561b5a700000000000000000"}}&sort={"_id": 1}
```

If forced to sort by non-unique fields, like `name.last`, it is possible to fall back on using the `skip` argument for paging, though it is not as efficient as using a unique indexed field. Additionally, paging using `skip` is only effective for small result sets (e.g. less than a few hundred records).

In the below example, we have a custom "Conversation" object. Suppose there are 20 conversations available to a user. An initial call to `GET /conversations?paths[]=_id&limit=2&sort={"_id": 1}` results in the following response:

```javascript
GET /c_conversations?paths[]=_id&limit=2&sort={"_id": 1}

{
    "data": [
        {
            "_id": "551c76c3bad12f302b343481",
            "object": "c_conversation"
        },        
        {
            "_id": "551c76c4bad12f302b343489",
            "object": "c_conversation"
        }
    ],
    "hasMore": true,
    "object": "list"
}
```

The response's `hasMore` property is true, so the caller knows there are more results. The last `_id` in the list is used in the next `where` argument like this:

```javascript
GET /conversations?paths[]=_id&limit=2&where={"_id": {"$gt": "551c76c4bad12f302b343489"}}&sort={"_id": 1}

{
    "data": [
        {
            "_id": "551c76c3bad12f302b343492",
            "object": "c_conversation"
        },        
        {
            "_id": "551c76c4bad12f302b343511",
            "object": "c_conversation"
        }
    ],
    "hasMore": true,
    "object": "list"
}
```

#### List Property Paging

\
Lists of contexts can be paged by prefixing query arguments with the property name. For example:

```javascript
GET /c_patientfiles/550891732390ac1832f3317f/?paths[]=connections.access&connections.where={"_id":{"$gt":"550b9a25c59c1ef032ab641c"}}

{
    "_id": "550891732390ac1832f3317f",
    "object": "c_patientfile",
    "connections": {
        "object": "list",
        "hasMore": "false",
        "data: [{
             "_id": "551ce5dfcd3227a41dfa7e9d",
             "object": "connection",
             "access": 2            
         }]
     }     
 }
```
