Parse Server Unity SDKの使い方（データストアクエリー操作）

[ニフクラ mobile backendは3月末で終了します](https://mbaas.nifcloud.com/info/2023/12/post-171.html)。

ニフクラ mobile backendからの移行先として、お勧めしているのが[Parse Server](https://parseplatform.org/)です。設計思想が近く、変更するコード量が少なく済むのではないかと思います。

Parse ServerではUnity向けにSDKを提供していますが、ドキュメントは英語のみとなっています。そこで、各機能の使い方を解説します。今回はクエリーの使い方です。

## Unity SDKのインストール

Unity SDKのインストールは、NuGetを使う方法が紹介されています。Unity側であらかじめ設定が必要なので、下記記事を参考にNuGetの設定を追加します。

[Unity で NuGet パッケージを利用する \#Unity \- Qiita](https://qiita.com/akiojin/items/ac05392d97abb8797dcd)

そして、ParseのSDKは下記URLにて公開されています。

[NuGet Gallery \| parse 2\.0\.0\-develop\-1](https://www.nuget.org/packages/parse/absoluteLatest)

## 制限

Unity SDKは、Unity 5.2.x以降が必須です。

## link.xmlの作成

アセットフォルダの中に `link.xml` を作成し、下記内容を記述します。

```xml
<linker>
  <assembly fullname="UnityEngine">
    <type fullname="UnityEngine.iOS.NotificationServices" preserve="all"/>
    <type fullname="UnityEngine.iOS.RemoteNotification" preserve="all"/>
    <type fullname="UnityEngine.AndroidJavaClass" preserve="all"/>
    <type fullname="UnityEngine.AndroidJavaObject" preserve="all"/>
  </assembly>

  <assembly fullname="Parse.Unity">
    <namespace fullname="Parse" preserve="all"/>
    <namespace fullname="Parse.Internal" preserve="all"/>
  </assembly>
</linker>
```

## 初期化

まず `Parse` を読み込みます。

```csharp
using Parse;
```

初期化は2つの方法があります。 `2` の方法はマスターキーを指定もできるので、 C#としてデスクトップアプリやASP.NETの中で使う際に利用できる方法になります。

```csharp
// 1. キーを指定して初期化
ParseClient client = new ParseClient("Your Application ID", "The Parse Server Instance Host URI", "Your .NET Key");

// 2. 詳細を指定して初期化
ParseClient client = new ParseClient(new ServerConnectionData
{
    ApplicationID = "Your Application ID",
    ServerURI = "The Parse Server Instance Host URI",
    Key = "Your .NET Key", // This is unnecessary if a value for MasterKey is specified.
    MasterKey = "Your Master Key",
    Headers = new Dictionary<string, string>
    {
        ["X-Extra-Header"] = "Some Value"
    }
});
```

## データの取得

データの取得には `ParseObject.GetQuery` を利用します。基本形は以下の通りです。

```csharp

var query = ParseObject.GetQuery("GameScore")
    .WhereEqualTo("playerName", "Dan Stemkoski");
query.FindAsync().ContinueWith(t =>
{
    IEnumerable<ParseObject> results = t.Result;
});
```

## 絞り込み条件

絞り込み条件は `WhereEqualTo` などを使います。他にも `WhereContainedIn` や `WhereExists` などがあります。以下は `Where` からはじまっているメソッドの一覧です。

- WhereContainedIn
- WhereContains	
- WhereContainsAll
- WhereDoesNotExist	
- WhereDoesNotMatchesKeyInQuery
- WhereDoesNotMatchQuery
- WhereEndsWith	
- WhereEqualTo	
- WhereExists	
- WhereGreaterThan	
- WhereGreaterThanOrEqualTo	
- WhereLessThan	
- WhereLessThanOrEqualTo	
- WhereMatches(String, String)	
- WhereMatches(String, Regex)	
- WhereMatches(String, String, String)	
- WhereMatches(String, Regex, String)	
- WhereMatchesKeyInQuery
- WhereMatchesQuery
- WhereNear	
- WhereNotContainedIn
- WhereNotEqualTo	
- WhereStartsWith	
- WhereWithinDistance	
- WhereWithinGeoBox

## 最初の結果だけが必要な場合

最初の結果だけが必要な場合は `FirstAsync` を使います。この場合は、配列ではなくParseObjectが返ってきます。

```csharp
var query = ParseObject.GetQuery("GameScore")
    .WhereEqualTo("playerEmail", "dstemkoski@example.com");
query.FirstAsync().ContinueWith(t =>
{
    ParseObject obj = t.Result;
});
```

## 取得件数の絞り込み

取得件数を制限したり、ページネーションを実装する際には、 `Limit` と `Skip` を使います。

```csharp
query = query.Limit(10);
query = query.Skip(10);
```

## ソート

ソートは `orderByAscending` と `orderByDescending` を使います。

```csharp
query.orderByAscending("score")
query.orderByDescending("score")
```

ソートキーを追加する際には、 `OrderBy` と `OrderByDescending` を使います。

```csharp
query.OrderBy("score")
query.OrderByDescending("score")
```

## 件数の取得

件数を取得する際には、 `CountAsync` を使います。

```csharp
var query = ParseObject.GetQuery("GameScore")
    .WhereEqualTo("playerName", "Sean Plott");
query.CountAsync().ContinueWith(t =>
{
    int count = t.Result;
});
```

## or条件

or条件を使う際には、 `or` を使います。

```csharp
var lotsOfWins = ParseObject.GetQuery("Player")
    .WhereGreaterThan("wins", 150);
var fewWins = ParseObject.GetQuery("Player")
    .WhereLessThan("wins", 5);
ParseQuery<ParseObject> query = lotsOfWins.Or(fewWins);
```

## まとめ

Parse ServerとNCMBのデータストア操作は、Unity SDK同士では大きくは異なりません。載せ替える際には、大きなコードにはならなそうです。ParseのUnity SDKの方が、クエリー操作の際にはメソッドが多そうです。

データの管理方法などはParse ServerとNCMBで似ています。他のmBaaSと比べると、全体の修正量はそこまで多くないと思われます。載せ替え先として検討に挙げてください。

[Unity Developers Guide \| Parse](https://docs.parseplatform.org/unity/guide/)