Couchbase Lite機能解説：クエリ③ JOIN、GROUP BY、ORDER BY

## はじめに

本稿では、Couchbase Liteデータベースに対するクエリにおける、JOIN、GROUP BY、ORDER BYスタートメント（相当の操作）について、コード例を示して紹介します。


## JOIN

### 用途
JOIN句を使用すると、JOINステートメントで指定された基準によってリンクされている複数のドキュメントからデータを選択できます。

### 例
航空会社の詳細を、航空会社IDでリンクされたルートの詳細と組み合わせて表示します。


```java
Query query = QueryBuilder.select(
    SelectResult.expression(Expression.property("name").from("airline")),
    SelectResult.expression(Expression.property("callsign").from("airline")),
    SelectResult.expression(Expression.property("destinationairport").from("route")),
    SelectResult.expression(Expression.property("stops").from("route")),
    SelectResult.expression(Expression.property("airline").from("route")))
    .from(DataSource.database(database).as("airline"))
    .join(Join.join(DataSource.database(database).as("route"))
        .on(Meta.id.from("airline").equalTo(Expression.property("airlineid").from("route"))))
    .where(Expression.property("type").from("route").equalTo(Expression.string("route"))
        .and(Expression.property("type").from("airline").equalTo(Expression.string("airline")))
        .and(Expression.property("sourceairport").from("route").equalTo(Expression.string("RIX"))));
for (Result result : query.execute()) {
         Log.w("Sample", String.format("%s", result.toMap().toString()));
}
```

## GROUP BY

### 用途
最終的な射影が生成される前に、結果セットのデータに対してグループ化を行います。

### 例
高度300フィート以上の空港の数を検索し、国とタイムゾーンごとに結果をグループ化します。

#### データモデル

```JSON
{
    "_id": "airport123",
    "type": "airport",
    "country": "United States",
    "geo": { "alt": 456 },
    "tz": "America/Anchorage"
}
```

#### クエリ
この例は、高度が300フィートを超えるすべての空港を選択するクエリを示しています。出力は、国およびタイムゾーンごとにグループ化されます。

```JAVA
Query query = QueryBuilder.select(
    SelectResult.expression(Function.count(Expression.string("*"))),
    SelectResult.property("country"),
    SelectResult.property("tz"))
    .from(DataSource.database(database))
    .where(Expression.property("type").equalTo(Expression.string("airport"))
        .and(Expression.property("geo.alt").greaterThanOrEqualTo(Expression.intValue(300))))
    .groupBy(
        Expression.property("country"),
        Expression.property("tz"))
    .orderBy(Ordering.expression(Function.count(Expression.string("*"))).descending());
for (Result result : query.execute()) {
    Log.i(
        "Sample",
        String.format(
            "There are %d airports on the %s timezone located in %s and above 300ft",
            result.getInt("$1"),
            result.getString("tz"),
            result.getString("country")));
}
```



## ORDER BY

### 用途
特定の式の結果に基づいてクエリの結果を並べ替えることができます。

### 例
「title」プロパティの値の昇順で並べ替えられた、「type」プロパティが「hotel」に等しいドキュメントが返されます。


```JAVA
Query query = QueryBuilder
    .select(
        SelectResult.expression(Meta.id),
        SelectResult.property("name"))
    .from(DataSource.database(database))
    .where(Expression.property("type").equalTo(Expression.string("hotel")))
    .orderBy(Ordering.property("name").ascending())
    .limit(Expression.intValue(10));
For (Result result : query.execute()) {
    Log.i("Sample", String.format("%s", result.toMap()));
}
```


クエリは、次の出力を生成します。

```
Aberdyfi
Achiltibuie
Altrincham
Ambleside
Annan
Ardèche
Armagh
Avignon
```