Let me code again...

Welcome to ijokarumawak's blog :)

N1QL INSERT

Couchbase Advent Calendar、12/10分の記事です。今日は4.1からサポートされたDMLのINSERTをご紹介します。

INSERTステートメント

キースペースに新規レコードを挿入します。

ドキュメントをINSERT INTOで作成することができます。INSERTの実行は同じ名前のドキュメントが存在しない場合のみ成功します。ドキュメントが存在する場合、INSERTは失敗します。

N1QLのドキュメントを見ていると、以下の様なシンタックス定義が記載されています。この定義では、大文字で表記されている部分はN1QLの予約語なので、そのまま使います。[insert-values | insert-select]はinsert-values形式か、insert-select形式の二つが選べるという意味になります。 シンタックス定義の表記方法は、Conventionsに記載されています。

insert:

INSERT INTO keyspace-ref [insert-values | insert-select] [returning-clause] 

シンタックス1: insert-values形式

まず、insert-valuesを見てみましょう。

insert-values:

 [ (  [ PRIMARY ] KEY , VALUE ) ]  values-clause [, values-clause]* 

さらにここで参照している、values-clauseも必要ですね。

values-clause:

VALUES ( expression , expression ) 

expressionまでたどり着くともう先は見なくて良いでしょう。expressionは何か値を返すための式になる部分です。リテラルの"foo"や、関数の実行結果、SELECTの結果などになります。

まとめると、

INSERT INTO keyspace-ref
([PRIMARY] KEY, VALUE)
VALUES ( expression , expression );

ということですね、values-clauseは繰り返しで書けるようになっています。

早速試してみましょう!

-- サンプル1: JSONドキュメントをINSERTする
INSERT INTO `default`
(PRIMARY KEY, VALUE)
VALUES ( "foo" , {"name": "foo", "age": 34} );

INSERTされたドキュメント:

{ "age": 34, "name": "foo" }	

PRIMARYは書いても書かなくても構いません。

シンタックス2: insert-select形式

insert-select:

( [PRIMARY] KEY expression [ , VALUE expression ] ) select 

selectはまた大きなトピックなので、ここでは細かく掘り下げませんが、select文のことですね。

ということで、まとめると、

INSERT INTO keyspace-ref
([PRIMARY] KEY expression [, VALUE expression])
select;

ですね。それでは試してみましょう!

-- サンプル2: SELECTの結果からJSONドキュメントをINSERTする
INSERT INTO `default`
(PRIMARY KEY "bar", VALUE {"name": "bar", "age": 5, "father": foo})
SELECT * FROM `default` AS foo USE KEYS "foo";

INSERTされたドキュメント:

{ "age": 5, "father": { "age": 34, "name": "foo" }, "name": "bar" }	

実行結果として作成したドキュメントを返却

returning-clauseを使わないと、N1QL実行結果は空っぽのARRAYになってしまいます。INSERTしたドキュメントを返す場合は以下のように実行します:

-- サンプル3: 集計結果のJSONドキュメントを保存する
INSERT INTO `default` AS r
(PRIMARY KEY UUID(), VALUE {
    "count": cnt, "avg": avg, "min": min, "max": max})
SELECT COUNT(u) AS cnt, AVG(u.age) AS avg,
  MAX(u.age) AS max, MIN(u.age) AS min
  FROM `default` AS u WHERE u.age IS NOT MISSING
RETURNING r

実行結果は次のように返却されます:

[
  {
    "r": {
      "avg": 16.6,
      "count": 5,
      "max": 34,
      "min": 5
    }
  }
]

まとめ

N1QLのドキュメントに記載されているシンタックスの読み方やサンプルのINSERT文をご紹介しました。SQLでおなじみのシンプルな構文ですが、JSONを扱うとなると新鮮ですね。

最後のサンプル3では、インサートするドキュメントのkeyとしてUUID関数を使ってみましたが、ここで発番した値はどうやって返せば良いのでしょう。META(r).idを試しましたが取れなかったので、次回に持ち越します!