ファイルのアップロード
クライアントは、HTTPのmultipart/form-dataエンコーディングで、Machbase Neoに任意のファイルをアップロードできます。 添付したファイルは指定ディレクトリに保存され、 データベースは、そのファイルのメタデータをJSON文字列として列に保存します。
各パートの名前を列名、値をデータの文字列表現として、multipart/form-data形式で送信します。
保存先ディレクトリを指定するには、JSON型の列にファイルを添付し、X-Store-Dirヘッダーを送信します。
X-Store-Dirのディレクトリがない場合は、サーバーが自動作成します。
ファイル本体は、UUID形式の一意の名前で、そのディレクトリに保存されます。
ファイルのアップロード
以下の例では、STASHテーブルが作成済みであることを前提とします。
CREATE TAG TABLE STASH(
NAME VARCHAR(80) primary key,
TIME DATETIME basetime,
DATA JSON
)この例では、Visual Studio CodeのREST Client拡張機能を使用します。
```http
POST http://127.0.0.1:5654/db/write/STASH
Content-Type: multipart/form-data; boundary=----Boundary7MA4YWxkTrZu0gW
------Boundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="NAME"
camera-1
------Boundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="TIME"
now
------Boundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="DATA"; filename="image_file.svg"
X-Store-Dir: /tmp/store
Content-Type: image/svg
<svg xmlns="http://w3.org" width="100" height="100" viewBox="0 0 100 100">
<rect width="100" height="100" fill="red" />
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
------Boundary7MA4YWxkTrZu0gW--
```レスポンスメッセージ
アップロードが完了すると、サーバーは保存したファイルの情報を以下のように返します。
- ID : サーバーが割り当てた一意のID
- FN : 元のファイル名
- SZ : ファイルサイズ
- CT : コンテンツタイプ
- SD : サーバー側の保存先ディレクトリのパス
{
"success":true,
"reason":"success, 1 record(s) inserted",
"elapse":"10.611208ms",
"data":{
"files":{
"DATA":{
"ID":"1f174fd2-cbd9-6d0e-b8a7-23fa7e810e6d",
"FN":"image_file.svg",
"SZ":177,
"CT":"image/svg+xml",
"SD":"/tmp/store"
}
}
}
}X-Store-Dir
アップロードしたファイルは、X-Store-Dirヘッダーのディレクトリに保存され、
ファイル名は、応答に含まれるID値に基づいて生成されます。
前述の例のように、各パートのヘッダーにX-Store-Dirを含めることも、
リクエスト全体のヘッダーに指定することもできます。
${data}X-Store-Dirのパスに${data}を使用すると、データベースのホームディレクトリを表します。このディレクトリは、machbase-neoの起動時に--dataで指定します。省略した場合は、実行ファイルのディレクトリ配下のmachbase_homeを既定値として使用します。詳細は、コマンドラインフラグを参照してください。
たとえば、X-Store-Dir: ${data}/storeを指定すると、ファイルはsome/path/to/machbase_home/store/file_name_is_ID_of_the_responseに保存されます。
メタデータ
上記のDATA列は、アップロードしたファイルのメタ情報を含むJSON形式の文字列として取得できます。
SELECT DATA FROM STASH
WHERE NAME = 'camera-1';JSON Pathを使用することもできます。
SELECT DATA FROM STASH
WHERE NAME = 'camera-1'
AND DATA->'$.FN' = 'image_file.svg';/db/query 検索
以下は、/db/query APIでSELECTクエリを実行する例です。
```http
GET http://127.0.0.1:5654/db/query
?q=select DATA from STASH where NAME = 'camera-1'
```JSON Pathの検索:->表記
```http
GET http://127.0.0.1:5654/db/query
?q=select DATA from STASH where NAME = 'camera-1' and DATA->'$.FN' = 'image_file.svg'
```DATA列には、以下のファイル情報が保存されています。
{
"data": {
"columns": [ "DATA" ],
"types": [ "string" ],
"rows": [
[
"{\"ID\":\"1ef8a87f-96bd-6576-9ff5-972fa7638db8\",\"FN\":\"image_file.svg\",\"SZ\":177,\"CT\":\"image/svg+xml\",\"SD\":\"/tmp/store\"}"
]
]
},
"success": true,
"reason": "success",
"elapse": "843.666µs"
}JSON型の列から特定のフィールドを抽出するには、JSON Pathを使用します。
```http
GET http://127.0.0.1:5654/db/query
?format=ndjson
&q=SELECT NAME, TIME, DATA->'$.ID' as FID FROM STASH WHERE NAME = 'camera-1'
```{"NAME":"camera-1","TIME":1728950208158594000,"FID":"1ef8a87f-96bd-6576-9ff5-972fa7638db8"}
{"NAME":"camera-1","TIME":1728953137384133000,"FID":"1ef8a8ec-b602-6cac-8fb1-ac9c0c1b981b"}ファイル内容の取得
ファイル本体には、クエリAPIでアクセスできます。
http://{server_address}/db/query/file/{table}/{column}/{ID}
TAGテーブルの場合は、tagパラメーターを指定すると応答を高速化できます。
http://{server_address}/db/query/file/{tag_table}/{column}/{ID}?tag=camera-1
LOGテーブルのIDは、レコードの挿入時刻に基づきます。TAGテーブルでは、レコードの基準時刻列からIDを生成します。
IDにはタイムスタンプ情報が含まれるため、Machbase NeoはTAGテーブルではTIME between A and B、LOGテーブルでは_ARRIVAL_TIME between A and Bを使い、検索範囲を絞り込みます。
IDのタイムスタンプは、基準時刻やLOGテーブルの_ARRIVAL_TIMEと完全には一致しませんが、検索性能の改善に役立ちます。
HTTP GET
```http
GET http://127.0.0.1:5654/db/query/file/STASH/DATA/1ef8a87f-96bd-6576-9ff5-972fa7638db8
```HTMLでの<img>の使用
<html>
<body>
<img src="http://127.0.0.1:5654/db/query/file/STASH/DATA/1ef8a87f-96bd-6576-9ff5-972fa7638db8"/>
</body>
</html>TAGテーブルでタグ名が分かっている場合は、tagクエリパラメーターで検索性能を向上できます。
<html>
<body>
<img src="http://127.0.0.1:5654/db/query/file/STASH/DATA/1ef8a87f-96bd-6576-9ff5-972fa7638db8?tag=camera-1"/>
</body>
</html>例
JavaScript
JavaScriptでファイルをアップロードする例です。
const request = require('request');
const fs = require('fs');
let req = {
method: 'POST',
url: 'http://127.0.0.1:5654/db/write/STASH',
headers: {"X-Store-Dir": "/tmp/store"},
formData: {
NAME: 'camera-1',
TIME: 'now',
DATA: fs.createReadStream('./image_file.svg'),
},
};
request(req, function(err, res, body){
if (err) { console.log(err);
} else { console.log(body); }
})Python
Pythonでファイルをアップロードする例です。
from pathlib import Path
import requests
url = "http://127.0.0.1:5654/db/write/STASH"
file_path = Path("./image_file.svg")
with file_path.open("rb") as image_file:
response = requests.post(
url,
headers={"X-Store-Dir": "/tmp/store"},
data={"NAME": "camera-1", "TIME": "now"},
files={"DATA": (file_path.name, image_file, "image/svg")},
)
response.raise_for_status()
print(response.text)