get_count_data
Count data records in Japan's MLIT Data Platform by applying keyword searches, location filters, or attribute conditions, with options to aggregate results by dataset or specific attributes.
Instructions
特定のデータセットに含まれるデータや、指定した範囲、日付など、指定した検索条件に一致するデータの件数を取得する。分類ごとの集計も可能。
使い方:
- キーワード / メタデータ / 空間条件を組み合わせて、件数のみを高速に把握できます。
- 集計の切り口は `slice_type` で指定:
- "dataset": カタログ→データセットの2段階で件数を返す(全カタログ/全データセットの分布を俯瞰)
- "attribute": 任意属性ごとの上位出現値を `slice_size` 件まで取得(最大50)。必要なら `slice_sub_attribute_name` で下位分類も可能。
- 空間条件(矩形/円)は `location_*` 引数により内部で `locationFilter` に変換。
- 属性条件は `catalog_id` / `dataset_id` / `prefecture_code` / `municipality_code` / `address` などを内部で `attributeFilter` に変換。
例:
- キーワード「橋梁」をデータセット別に件数集計:
term="橋梁", slice_type="dataset"
- 都道府県別トップ10 + その下でデータセット別内訳:
term="", slice_type="attribute",
slice_attribute_name="DPF:prefecture_code", slice_size=10,
slice_sub_attribute_name="DPF:dataset_id", slice_sub_size=10
- 矩形範囲(東京都心部)× カタログIDで件数:
term="", catalog_id="dimaps",
location_rectangle_top_left_lat=35.80, location_rectangle_top_left_lon=139.55,
location_rectangle_bottom_right_lat=35.60, location_rectangle_bottom_right_lon=139.85,
slice_type="attribute", slice_attribute_name="DPF:dataset_id", slice_size=20
- 円範囲(東京駅 半径500m)× データセット内件数:
term="", dataset_id="cals_construction",
location_lat=35.681236, location_lon=139.767125, location_distance=500,
slice_type="attribute", slice_attribute_name="DPF:title", slice_size=10
注意:
- 公式仕様上、`locationFilter`(空間条件)**のみでは検索不可**。必ず `term` か `attributeFilter`(本ツールでは catalog_id / dataset_id / prefecture_code / municipality_code / address 等)を併用してください。
- `slice_size` の最大は **50**。上位出現値のみが返却され、それ以外は省略されます。上位分類の `dataCount` には下位分類で表示されない分も含まれます。
- `attributeFilter` は `is/similar/gte/gt/lte/lt` に対応し、`AND` / `OR` でネスト結合が可能(本ツールでは単純条件を主にサポート)。
- `locationFilter` は `rectangle` / `geoDistance` のほか `union` / `intersection` に対応。ただし **同クラス内の他メンバーと同時利用不可**、かつ **入れ子(ネスト)不可**。
- 座標は WGS84。矩形は「北西(top_left)→南東(bottom_right)」の順で指定。
- パフォーマンス観点から、まず `get_count_data` でボリューム見積り → 必要に応じて `get_all_data` で実データ取得が推奨。Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| term | No | 検索キーワード。属性フィルタのみの場合は省略可能 | |
| phrase_match | No | フレーズマッチモード | |
| prefecture_code | No | 都道府県コードで絞り込み | |
| municipality_code | No | 市区町村コードで絞り込み | |
| address | No | 住所で絞り込み | |
| catalog_id | No | カタログIDで絞り込み | |
| dataset_id | No | データセットIDで絞り込み。集計対象の指定に必須 | |
| location_rectangle_top_left_lat | No | 矩形範囲の左上緯度 | |
| location_rectangle_top_left_lon | No | 矩形範囲の左上経度 | |
| location_rectangle_bottom_right_lat | No | 矩形範囲の右下緯度 | |
| location_rectangle_bottom_right_lon | No | 矩形範囲の右下経度 | |
| location_lat | No | 中心地点の緯度(円形範囲検索用) | |
| location_lon | No | 中心地点の経度(円形範囲検索用) | |
| location_distance | No | 検索半径(メートル単位、円形範囲検索用) | |
| slice_type | No | 集計タイプ: - 'attribute': 属性別に集計(最も一般的) - 'dataset': データセット別に集計 省略時は属性指定があれば自動的に'attribute'になります | |
| slice_attribute_name | No | 集計する属性名(ネームスペース付き)。 例: - 'DPF:year' → 年度別集計 - 'DPF:prefecture_code' → 都道府県別集計 - 'RSDB:tenken.nendo' → 点検年度別集計 指定すると自動的にslice_type='attribute'になります | |
| slice_size | No | 集計結果の最大件数(1-50)。上位N件のみ取得したい場合に指定 | |
| slice_sub_attribute_name | No | 2段階目の集計属性名。 例: slice_attribute_name='DPF:prefecture_code', slice_sub_attribute_name='DPF:year' → 都道府県別 × 年度別のクロス集計 | |
| slice_sub_size | No | 2段階目の集計結果の最大件数 |
Implementation Reference
- src/server.py:1364-1431 (handler)The tool 'get_count_data' is handled here by assembling slice settings and calling client.count_data.
elif name == "get_count_data": # --- Build sub-slice (plain dict, camelCase) --- sub_dict = None if arguments.get("slice_sub_attribute_name") or arguments.get("slice_sub_size") is not None: sub_dict = { "attributeName": arguments.get("slice_sub_attribute_name") or "", } if arguments.get("slice_sub_size") is not None: sub_dict["size"] = int(arguments.get("slice_sub_size")) # --- Build attribute slice (plain dict, camelCase) --- attr_dict = None if ( arguments.get("slice_attribute_name") or arguments.get("slice_size") is not None or sub_dict is not None ): attr_dict = { "attributeName": arguments.get("slice_attribute_name") or "", } if arguments.get("slice_size") is not None: attr_dict["size"] = int(arguments.get("slice_size")) if sub_dict is not None: # penting: key GraphQL adalah subSliceSetting (camelCase) attr_dict["subSliceSetting"] = sub_dict # --- Decide slice_type --- slice_type = arguments.get("slice_type") if slice_type is None and attr_dict is not None: slice_type = "attribute" # --- Assemble slice_setting (plain dict; do not use Pydantic yet) --- slice_setting = None if slice_type == "dataset": slice_setting = {"type": "dataset"} elif slice_type is not None or attr_dict is not None: slice_setting = {"type": slice_type or "attribute"} if attr_dict is not None: # important: GraphQL key is attributeSliceSetting (camelCase) slice_setting["attributeSliceSetting"] = attr_dict # --- Normalize region args (same as before) --- arguments = await _auto_normalize_region_args(arguments, client) # --- Build CountDataInput (PASS-THROUGH dict slice_setting already assembled) --- p = CountDataInput.model_validate({ "term": arguments.get("term"), "phrase_match": arguments.get("phrase_match"), "prefecture_code": arguments.get("prefecture_code"), "municipality_code": arguments.get("municipality_code"), "address": arguments.get("address"), "catalog_id": arguments.get("catalog_id"), "dataset_id": arguments.get("dataset_id"), "location_rectangle_top_left_lat": arguments.get("location_rectangle_top_left_lat"), "location_rectangle_top_left_lon": arguments.get("location_rectangle_top_left_lon"), "location_rectangle_bottom_right_lat": arguments.get("location_rectangle_bottom_right_lat"), "location_rectangle_bottom_right_lon": arguments.get("location_rectangle_bottom_right_lon"), "location_lat": arguments.get("location_lat"), "location_lon": arguments.get("location_lon"), "location_distance": arguments.get("location_distance"), "slice_setting": slice_setting, }) data = await client.count_data(p) return { "content": [{"type": "text", "text": json.dumps(data)}], "isError": False, } - src/client.py:949-1024 (handler)Implementation of the count_data method in MLITClient, which builds the GraphQL query for the countData API.
async def count_data(self, params: CountDataInput) -> Dict[str, Any]: attr_filter = self.make_attribute_filter_for_countdata( prefecture_code=params.prefecture_code, municipality_code=params.municipality_code, address=params.address, catalog_id=params.catalog_id, dataset_id=params.dataset_id, ) loc_filter = None if all(v is not None for v in [ params.location_rectangle_top_left_lat, params.location_rectangle_top_left_lon, params.location_rectangle_bottom_right_lat, params.location_rectangle_bottom_right_lon ]): loc_filter = self.make_rectangle_filter( float(params.location_rectangle_top_left_lat), # type: ignore float(params.location_rectangle_top_left_lon), # type: ignore float(params.location_rectangle_bottom_right_lat), # type: ignore float(params.location_rectangle_bottom_right_lon), # type: ignore ) elif all(v is not None for v in [ params.location_lat, params.location_lon, params.location_distance ]): loc_filter = self.make_geodistance_filter( float(params.location_lat), # type: ignore float(params.location_lon), # type: ignore float(params.location_distance), # type: ignore ) effective_term: Optional[str] = params.term if effective_term is None and (attr_filter is not None or loc_filter is not None): effective_term = "" # BRIDGE: top-level slice_* → slice_setting (kalau belum ada) slice_setting_obj = params.slice_setting if slice_setting_obj is None: st = (getattr(params, "slice_type", None) or "").strip().lower() if st == "dataset": slice_setting_obj = {"type": "dataset"} elif st == "attribute": # Build attributeSliceSetting from top-level fields name = self._normalize_attr_name(getattr(params, "slice_attribute_name", "") or "") size = getattr(params, "slice_size", None) sub_name = self._normalize_attr_name(getattr(params, "slice_sub_attribute_name", "") or "") sub_size = getattr(params, "slice_sub_size", None) attr_block: Dict[str, Any] = {} if name: attr_block["attributeName"] = name if isinstance(size, int): attr_block["size"] = int(size) sub_block: Dict[str, Any] = {} if sub_name: sub_block["attributeName"] = sub_name if isinstance(sub_size, int): sub_block["size"] = int(sub_size) if sub_block: attr_block["subSliceSetting"] = sub_block slice_setting_obj = ( {"type": "attribute", "attributeSliceSetting": attr_block} if attr_block else {"type": "attribute"} ) q = self.build_count_data( term=effective_term, phrase_match=params.phrase_match, attribute_filter=attr_filter, location_filter=loc_filter, slice_setting=slice_setting_obj, ) return await self.post_query(q) - src/server.py:720-851 (registration)Registration of the 'get_count_data' tool with its input schema definition.
types.Tool( name="get_count_data", description="""特定のデータセットに含まれるデータや、指定した範囲、日付など、指定した検索条件に一致するデータの件数を取得する。分類ごとの集計も可能。 使い方: - キーワード / メタデータ / 空間条件を組み合わせて、件数のみを高速に把握できます。 - 集計の切り口は `slice_type` で指定: - "dataset": カタログ→データセットの2段階で件数を返す(全カタログ/全データセットの分布を俯瞰) - "attribute": 任意属性ごとの上位出現値を `slice_size` 件まで取得(最大50)。必要なら `slice_sub_attribute_name` で下位分類も可能。 - 空間条件(矩形/円)は `location_*` 引数により内部で `locationFilter` に変換。 - 属性条件は `catalog_id` / `dataset_id` / `prefecture_code` / `municipality_code` / `address` などを内部で `attributeFilter` に変換。 例: - キーワード「橋梁」をデータセット別に件数集計: term="橋梁", slice_type="dataset" - 都道府県別トップ10 + その下でデータセット別内訳: term="", slice_type="attribute", slice_attribute_name="DPF:prefecture_code", slice_size=10, slice_sub_attribute_name="DPF:dataset_id", slice_sub_size=10 - 矩形範囲(東京都心部)× カタログIDで件数: term="", catalog_id="dimaps", location_rectangle_top_left_lat=35.80, location_rectangle_top_left_lon=139.55, location_rectangle_bottom_right_lat=35.60, location_rectangle_bottom_right_lon=139.85, slice_type="attribute", slice_attribute_name="DPF:dataset_id", slice_size=20 - 円範囲(東京駅 半径500m)× データセット内件数: term="", dataset_id="cals_construction", location_lat=35.681236, location_lon=139.767125, location_distance=500, slice_type="attribute", slice_attribute_name="DPF:title", slice_size=10 注意: - 公式仕様上、`locationFilter`(空間条件)**のみでは検索不可**。必ず `term` か `attributeFilter`(本ツールでは catalog_id / dataset_id / prefecture_code / municipality_code / address 等)を併用してください。 - `slice_size` の最大は **50**。上位出現値のみが返却され、それ以外は省略されます。上位分類の `dataCount` には下位分類で表示されない分も含まれます。 - `attributeFilter` は `is/similar/gte/gt/lte/lt` に対応し、`AND` / `OR` でネスト結合が可能(本ツールでは単純条件を主にサポート)。 - `locationFilter` は `rectangle` / `geoDistance` のほか `union` / `intersection` に対応。ただし **同クラス内の他メンバーと同時利用不可**、かつ **入れ子(ネスト)不可**。 - 座標は WGS84。矩形は「北西(top_left)→南東(bottom_right)」の順で指定。 - パフォーマンス観点から、まず `get_count_data` でボリューム見積り → 必要に応じて `get_all_data` で実データ取得が推奨。""", inputSchema={ "type": "object", "properties": { "term": { "type": "string", "description": "検索キーワード。属性フィルタのみの場合は省略可能" }, "phrase_match": { "type": "boolean", "description": "フレーズマッチモード" }, "prefecture_code": { "type": "string", "description": "都道府県コードで絞り込み" }, "municipality_code": { "type": "string", "description": "市区町村コードで絞り込み" }, "address": { "type": "string", "description": "住所で絞り込み" }, "catalog_id": { "type": "string", "description": "カタログIDで絞り込み" }, "dataset_id": { "type": "string", "description": "データセットIDで絞り込み。集計対象の指定に必須" }, "location_rectangle_top_left_lat": { "type": "number", "description": "矩形範囲の左上緯度" }, "location_rectangle_top_left_lon": { "type": "number", "description": "矩形範囲の左上経度" }, "location_rectangle_bottom_right_lat": { "type": "number", "description": "矩形範囲の右下緯度" }, "location_rectangle_bottom_right_lon": { "type": "number", "description": "矩形範囲の右下経度" }, "location_lat": { "type": "number", "description": "中心地点の緯度(円形範囲検索用)" }, "location_lon": { "type": "number", "description": "中心地点の経度(円形範囲検索用)" }, "location_distance": { "type": "number", "description": "検索半径(メートル単位、円形範囲検索用)" }, "slice_type": { "type": "string", "description": """集計タイプ: - 'attribute': 属性別に集計(最も一般的) - 'dataset': データセット別に集計 省略時は属性指定があれば自動的に'attribute'になります""" }, "slice_attribute_name": { "type": "string", "description": """集計する属性名(ネームスペース付き)。 例: - 'DPF:year' → 年度別集計 - 'DPF:prefecture_code' → 都道府県別集計 - 'RSDB:tenken.nendo' → 点検年度別集計 指定すると自動的にslice_type='attribute'になります""" }, "slice_size": { "type": "integer", "description": "集計結果の最大件数(1-50)。上位N件のみ取得したい場合に指定" }, "slice_sub_attribute_name": { "type": "string", "description": """2段階目の集計属性名。 例: slice_attribute_name='DPF:prefecture_code', slice_sub_attribute_name='DPF:year' → 都道府県別 × 年度別のクロス集計""" }, "slice_sub_size": { "type": "integer", "description": "2段階目の集計結果の最大件数" }, }, }, ),