スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Neo4jのRelationshipのプロパティの集計

最近、仕事でグラフデータベースのNeo4jを使っているので、Neo4jのネタも少しずつ増やしていこうかと思います。
今回は、Neo4jのリレーションのプロパティ値をCypherで集計する方法を紹介します。

■環境
Neo4j ver.2.0

■方法
以下のように複数のノードがプロパティを保持しているリレーションで関連付いている場合に始点のノードから
終点のノードの間に存在するリレーションのプロパティ値の合計を求める方法を説明します。
(下記の場合1+2+3で合計は6)

図:
(始点)‐1->(N1)-2->(N2)-3->(終点)

判例:
(名前) …ノード、()の中はノードのname属性の値
-数字-> …リレーション、数値はprop属性の値

では、まずは始点から終点までの全てのノード、リレーションを取得するクエリから。

match p=(s{name:'始点'})-[rel*]->(e{name:'終点'})
return p;

今回は始点と終点の間に複数ノードが存在する為、リレーションの指定に*を利用します。
この*は直接関連付いているノードの先にあるノードを検索できるようになります。
シンタックスは、以下のようになっており、どこまで先を検索するかの最大、最小値が
指定できるようになっています。
ちなみにNeo4jの世界では先のノードへ移ることをホップする(跳び越える)と表現しています。

Syntax:
-[:TYPE*minHops..maxHops]->

ここまで出来れば以下のクエリでプロパティ値が集計出来そうなのですが、こちらのクエリを実行すると
エラーとなってしまいます。

match p=(s{name:'始点'})-[rel*]->(e{name:'終点'})
return sum(rel.prop)
エラー内容:
Type mismatch: rel already defined with conflicting type Collection

sum()関数はノードのプロパティ値を集計する場合には正しく動作しますが、リレーションのプロパティ値の
集計にはどうやら使えないようです。
エラーメッセージからするとタイプミスマッチとなっているので、ノードのコレクションを想定していたところに
リレーションのコレクションが設定された為、エラーとなっているように解釈できそうな。。。(解釈が正しいかどうかは不明)

このようなケースでも集計が行えるようにNeo4jは「REDUCE」関数を用意してくれています。
このREDUCE関数を利用した集計クエリは以下の通りです。

match p=(s{name:'始点'})-[rel*]->(e{name:'終点'})
return reduce(totalProp = 0, relcol in rel | totalProp + relcol.prop) as total

REDUCE関数のシンタックスは以下の通りです。

Syntax:
REDUCE( accumulator = initial, identifier in collection | expression )

accumulator…合計値を格納する識別子、initialで初期値を設定する事ができます。
identifier…コレクションを格納する識別子。
collection…集計対象とするコレクションを指定(identifierに格納されます)。
expression…集計結果を算出する計算式を設定します。計算結果がaccumulatorに格納します。

今回のケースではtotalPropsをプロパティの集計値、match句で取得したリレーションのコレクションをrelcolに格納し、
計算式「totalProp + relcol.prop」によってprop属性の合計値がtotalPropに格納されるように設定しています。

以上です。

参考:
Neo4jマニュアル‐REDUCE関数
スポンサーサイト

SQL Serverのインスタンス名の確認

SQL Server2012のインスタンス名の確認方法。

■環境
SQL Server2012 Express
Windows 8

■内容
1.[コントロールパネル]→[管理ツール]→[コンピュータの管理]でウィンドウを開き、左側のツリーを以下のように辿ります。
 「サービスとアプリケーション」→「SQL Server構成マネージャ」→「SQL Serverのサービス」。
 「SQL Server(インスタンス名)」の形式でインスタンス名が確認できます。
 今回は、SQL Server Expressをデフォルトでインストールした時のインスタンス名「SQLEXPRESS」が表示されています。
 SQL Serverインスタンス名の確認
以上です。

AndroidアプリをURLから起動

今回はAndroidアプリをHTMLファイルの中のURLから起動する方法を紹介します。

■実装方法
1.インテントフィルタの設定
『AndroidManifest.xml』ファイルにインテントフィルターを宣言し、ブラウザからの起動に応答できるようにします。

AndroidManifext.xml

<activity
android:name="com.example.myapplication.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" android:host="test" android:path="/sample"/>

</intent-filter>
</activity>

カテゴリとして「android.intent.category.BROWSABLE」を設定する事でブラウザからの起動に応答できるようにします。
そのしたの「<data android:~」は起動する時のURLの設定です。

android:scheme … 起動時のURLのスキーム(必須)
android:host … 起動時のURLのホスト(必須)
android:pathPrefix … 起動時のURLのパス(任意)

上記の内容だと以下のURLでアプリが起動する事となります。

myapp://test/sample

2.htmlページ作成
アプリ起動用のhtmlファイルを作成します。今回はアプリ起動時にパラメータを渡すようにクエリを設定しています。

sample.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>アプリケーション起動サンプル</title>
</head>
<body>
<a href="myapp://test/sample?param1=パラメータ1&param2=パラメータ2">アプリケーションを起動</a>
</body>
</html>

上記URLの「param1=パラメータ1&param2=パラメータ2」がパラメータとなります。
こちらのhtmlをAndroid端末のローカルストレージに保存、もしくは適当なサーバに保存します。
(ローカルストレージに保存した場合は、エクスプローラを使ってファイル開く)

3.アプリの実装
URLから起動された時の処理を記述します。
今回は、パラメータを取得してTextViewに設定する処理を行っています。

@Override
protected void onResume() {
super.onResume();

Intent intent = getIntent();
String action = intent.getAction();

if (Intent.ACTION_VIEW.equals(action)) {
Uri uri = intent.getData();
if (uri != null) {
String param1 = uri.getQueryParameter("param1");
String param2 = uri.getQueryParameter("param2");
TextView txtView1 = (TextView)findViewById(R.id.textView);
TextView txtView2 = (TextView)findViewById(R.id.textView2);
txtView1.setText(param1);
txtView2.setText(param2);
}
}
}

intent.getData()でアプリを起動したURLが取得できます。
uri.getQueryParameter("パラメータ名")でクエリ―に設定したパラメータが取得し、こちらをTextViewに設定しています。

以上です。

ちなみに、AndroidのChromeブラウザのバージョン25以降からは、iframeのsrc属性でのアプリ起動が出来なくなっているらしく、intent://というスキームを使用するように変更になっているようです。

参考URL:
Android Intents with Chrome
Enabling Deep Links for App Content

C#でJSONのシリアライズとデシリアライズ

C#でJSONを扱う場合.NET Frameworkが標準で提供しているSystem.Runtime.Serialization名前空間のクラスが利用できるのですが、オープンソース(MITライセンス)で提供されているJSON.NETの方が扱いやすく便利そうなので今回はこちらを利用しています。

■URL
JSON.NET

■Visual Studioの設定
ますは、上記URLよりJSON.NETをダウンロードし「Newtonsoft.Json」名前空間を参照設定に追加。
以下のパッケージマネージャコマンドでインストールするとDL、参照設定の追加が自動で行われ便利です。

========================================
PM> Install-Package Newtonsoft.Json
========================================

■実装
最初はシリアライズ/デシリアライズ対象のクラス
========================================
namespace Test
{
    class Person
    {
        public string Name { get; set; }
        public string Address{ get; set; }
    }
}
========================================

シリアライズ例。シリアライズ/デシリアライズ共にJsonConvertクラスを利用します
========================================
var person = new Person()
{
    Name = "テスト太郎",
    Address = "東京都豊島区"
};

string json = JsonConvert.SerializeObject(person);
========================================
上記のコードで戻り値のjsonには、以下の文字列が格納されます。
{"Name":"テスト太郎","Address":"東京都豊島区"}

続いてデシリアライズの例。
========================================
string json = "{\"Name\":\"テスト太郎\",\"Address\":\"東京都豊島区\"}"
Person person = JsonConvert.DeserializeObject(json);
========================================
型パラメータでマッピングしたい型を指定します。
上記のコードでpersonオブジェクトのプロパティが設定された状態で返却されます。

ここで、気になるのがC#の場合、一般的にプロパティ名の先頭が大文字であるため、JSONで扱った場合のプロパティ名も先頭が大文字になる点です。一般的にJSONのプロパティ名は小文字が先頭になる為、今度はこちらのケースに対応する方法を説明します。

JsonConvertのシリアライズ/デシリアライズする時にどのように変換するのかJsonSerializerSettingsクラスで設定を行う事ができます。
こちらは、JsonConvertのSerializeObject、DesirializeObjectのそれぞれの引数として渡すことが出来る為、先頭小文字の設定を指示したJsonSerializerSettingsをこららのメソッドに渡す事で先頭小文字のプロパティ名に対応したJSONの変換が行えます。

それでは、早速シリアライズの例。
========================================
var person = new Person()
{
    Name = "テスト太郎",
    Address = "東京都豊島区"
};

string json = JsonConvert.SerializeObject(person,
        new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
========================================
上記のコードで戻り値のjsonの値。
{"name":"テスト太郎","address":"東京都豊島区"}

続いてデシリアライズの例。
========================================
string json = "{\"name\":\"テスト太郎\",\"nddress\":\"東京都豊島区\"}"
Person person = JsonConvert.DeserializeObject(json,
        new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
========================================
JsonSerializerSettingsのContractResolverにCamelCasePropertyNamesContractResolverのインスタンスを設定する事で先頭小文字のプロパティに対応します。

とまあ、ここまで書いたのですが、実はデシリアライズに関してはCamelCasePropertyNamesContractResolverを設定しなくても先頭小文字のプロパティに対応していました。
でも、シリアライズとデシリアライズで利用するResolverが違うのは少し気持ち悪いので、私は両方に指定して使おうと思います。
プロフィール

まこち

Author:まこち
スマートフォンのアプリ開発やWebサイト構築等を仕事や趣味でやっています。
最近はグラフデータベースも始めました。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。