0

问题:当需要的名称是动态/变量时,如何编写sqlite语句从嵌套对象中选择一个值。json同样重要的是,这可以通过单个sql语句完成。最终,这将从bash脚本中执行。

在下面的对象示例中,我需要列出数据库dot11.advertisedssid.ssid中的所有内容。一个可接受的解决方案是列出对象中存在的sql所有值,但我想了解如何查询动态名称(因此我可以获得其他嵌套值)。一般来说,我在我的陈述中使用我只是无法弄清楚如何获得 ssid 值(在这个例子中)!dot11.advertisedssid.ssidjsonjsonjson_extractsql

我怎么知道733545801字段名称是什么,然后我如何在json_extract语句中使用它?并为所有此类嵌套对象执行此操作。

例子:

一般来说,这就是我查询其他 json 值的方式。

select json_extract(devices.device,'$."dot11.device"."dot11.device.typeset"') from devices;

来自数据库的对象样本:

 "dot11.device": {
    "dot11.device.typeset": 257,
    "dot11.device.client_map": {

    },
    "dot11.device.num_client_aps": 0,
    "dot11.device.advertised_ssid_map": {
      "733545801": {
        "dot11.advertisedssid.ssid": "SampleFES-WiFi",
        "dot11.advertisedssid.ssidlen": 15,
        "dot11.advertisedssid.beacon": 1,
        "dot11.advertisedssid.probe_response": 1,
        "dot11.advertisedssid.channel": "6",
        "dot11.advertisedssid.ht_mode": "HT20",
        "dot11.advertisedssid.ht_center_1": 0,
        "dot11.advertisedssid.ht_center_2": 0,
        "dot11.advertisedssid.first_time": 1559567379,
        "dot11.advertisedssid.last_time": 1559567379,
        "dot11.advertisedssid.beacon_info": "",
        "dot11.advertisedssid.cloaked": 0,
        "dot11.advertisedssid.crypt_set": 268436162,
        "dot11.advertisedssid.maxrate": 65.000000,
        "dot11.advertisedssid.beaconrate": 10,
        "dot11.advertisedssid.beacons_sec": 2,
        "dot11.advertisedssid.ietag_checksum": 1220416683,
        "dot11.advertisedssid.wpa_mfp_required": 0,
        "dot11.advertisedssid.wpa_mfp_supported": 0,
        "dot11.advertisedssid.dot11d_country": "",
        "dot11.advertisedssid.dot11d_list": [
        ],
        "dot11.advertisedssid.wps_state": 0,
        "dot11.advertisedssid.dot11r_mobility": 0,
        "dot11.advertisedssid.dot11r_mobility_domain_id": 0,
        "dot11.advertisedssid.dot11e_qbss": 0,
        "dot11.advertisedssid.dot11e_qbss_stations": 0,
        "dot11.advertisedssid.dot11e_channel_utilization_perc": 0.000000,
        "dot11.advertisedssid.ccx_txpower": 0,
        "dot11.advertisedssid.cisco_client_mfp": 0,
        "dot11.advertisedssid.ie_tag_list": [
          0.000000,
          1.000000,
          3.000000,
          5.000000,
          42.000000,
          50.000000,
          48.000000,
          45.000000,
          61.000000,
          127.000000,
          221.000000
        ]
      }
    }

谢谢您的帮助!

PS。这是来自新kismet数据库和重新设计的架构。

这是整个对象:

   {
  "kismet.device.base.manuf": "Texas Instruments",
  "kismet.device.base.key": "4202770D00000000_AFB4F569D2380000",
  "kismet.device.base.macaddr": "38:D2:69:F5:B4:AF",
  "kismet.device.base.phyname": "IEEE802.11",
  "kismet.device.base.phyid": 0,
  "kismet.device.base.name": "LincolnFES-WiFi",
  "kismet.device.base.commonname": "LincolnFES-WiFi",
  "kismet.device.base.type": "Wi-Fi AP",
  "kismet.device.base.basic_type_set": 1,
  "kismet.device.base.crypt": "WPA2-PSK",
  "kismet.device.base.basic_crypt_set": 2,
  "kismet.device.base.first_time": 1559567379,
  "kismet.device.base.last_time": 1559567379,
  "kismet.device.base.mod_time": 1559567380,
  "kismet.device.base.packets.total": 3,
  "kismet.device.base.packets.rx": 0,
  "kismet.device.base.packets.tx": 0,
  "kismet.device.base.packets.llc": 3,
  "kismet.device.base.packets.error": 0,
  "kismet.device.base.packets.data": 0,
  "kismet.device.base.packets.crypt": 0,
  "kismet.device.base.packets.filtered": 0,
  "kismet.device.base.datasize": 0,
  "kismet.device.base.packets.rrd": {
    "kismet.common.rrd.last_time": 1559567383,
    "kismet.common.rrd.minute_vec": [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      1,
      2,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0
    ],
    "kismet.common.rrd.blank_val": 0,
    "kismet.common.rrd.aggregator": "default",
    "kismet.common.rrd.hour_vec": [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0
    ],
    "kismet.common.rrd.day_vec": [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0
    ]
  },
  "kismet.device.base.signal": {
    "kismet.common.signal.type": "dbm",
    "kismet.common.signal.last_signal": -56,
    "kismet.common.signal.last_noise": 0,
    "kismet.common.signal.min_signal": -74,
    "kismet.common.signal.min_noise": 0,
    "kismet.common.signal.max_signal": -56,
    "kismet.common.signal.max_noise": 0,
    "kismet.common.signal.maxseenrate": 10,
    "kismet.common.signal.encodingset": 1,
    "kismet.common.signal.carrierset": 1,
    "kismet.common.signal.signal_rrd": {
      "kismet.common.rrd.last_time": 1559567383,
      "kismet.common.rrd.minute_vec": [
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0
      ],
      "kismet.common.rrd.blank_val": 0,
      "kismet.common.rrd.aggregator": "peak_signal"
    }
  },
  "kismet.device.base.freq_khz_map": {
    "2437000.000000": 1,
    "2442000.000000": 1,
    "5500000.000000": 1
  },
  "kismet.device.base.channel": "6",
  "kismet.device.base.frequency": 2442000,
  "kismet.device.base.num_alerts": 0,
  "kismet.device.base.tags": {

  },
  "kismet.device.base.seenby": {
    "-1970862229": {
      "kismet.common.seenby.uuid": "5FE308BD-0000-0000-0000-00C0CAA60413",
      "kismet.common.seenby.first_time": 1559567379,
      "kismet.common.seenby.last_time": 1559567379,
      "kismet.common.seenby.num_packets": 3,
      "kismet.common.seenby.freq_khz_map": {
        "2437000.000000": 1,
        "2442000.000000": 1,
        "5500000.000000": 1
      },
      "kismet.common.seenby.signal": {
        "kismet.common.signal.type": "dbm",
        "kismet.common.signal.last_signal": -56,
        "kismet.common.signal.last_noise": 0,
        "kismet.common.signal.min_signal": -74,
        "kismet.common.signal.min_noise": 0,
        "kismet.common.signal.max_signal": -56,
        "kismet.common.signal.max_noise": 0,
        "kismet.common.signal.maxseenrate": 10,
        "kismet.common.signal.encodingset": 1,
        "kismet.common.signal.carrierset": 1,
        "kismet.common.signal.signal_rrd": {
          "kismet.common.rrd.last_time": 1559567383,
          "kismet.common.rrd.minute_vec": [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "kismet.common.rrd.blank_val": 0,
          "kismet.common.rrd.aggregator": "peak_signal"
        }
      }
    }
  },
  "kismet.device.base.server_uuid": "A8F71A2C-85F8-11E9-BA41-4B49534D4554",
  "dot11.device": {
    "dot11.device.typeset": 257,
    "dot11.device.client_map": {

    },
    "dot11.device.num_client_aps": 0,
    "dot11.device.advertised_ssid_map": {
      "733545801": {
        "dot11.advertisedssid.ssid": "LincolnFES-WiFi",
        "dot11.advertisedssid.ssidlen": 15,
        "dot11.advertisedssid.beacon": 1,
        "dot11.advertisedssid.probe_response": 1,
        "dot11.advertisedssid.channel": "6",
        "dot11.advertisedssid.ht_mode": "HT20",
        "dot11.advertisedssid.ht_center_1": 0,
        "dot11.advertisedssid.ht_center_2": 0,
        "dot11.advertisedssid.first_time": 1559567379,
        "dot11.advertisedssid.last_time": 1559567379,
        "dot11.advertisedssid.beacon_info": "",
        "dot11.advertisedssid.cloaked": 0,
        "dot11.advertisedssid.crypt_set": 268436162,
        "dot11.advertisedssid.maxrate": 65,
        "dot11.advertisedssid.beaconrate": 10,
        "dot11.advertisedssid.beacons_sec": 2,
        "dot11.advertisedssid.ietag_checksum": 1220416683,
        "dot11.advertisedssid.wpa_mfp_required": 0,
        "dot11.advertisedssid.wpa_mfp_supported": 0,
        "dot11.advertisedssid.dot11d_country": "",
        "dot11.advertisedssid.dot11d_list": [

        ],
        "dot11.advertisedssid.wps_state": 0,
        "dot11.advertisedssid.dot11r_mobility": 0,
        "dot11.advertisedssid.dot11r_mobility_domain_id": 0,
        "dot11.advertisedssid.dot11e_qbss": 0,
        "dot11.advertisedssid.dot11e_qbss_stations": 0,
        "dot11.advertisedssid.dot11e_channel_utilization_perc": 0,
        "dot11.advertisedssid.ccx_txpower": 0,
        "dot11.advertisedssid.cisco_client_mfp": 0,
        "dot11.advertisedssid.ie_tag_list": [
          0,
          1,
          3,
          5,
          42,
          50,
          48,
          45,
          61,
          127,
          221
        ]
      }
    },
    "dot11.device.num_advertised_ssids": 1,
    "dot11.device.probed_ssid_map": {

    },
    "dot11.device.num_probed_ssids": 0,
    "dot11.device.associated_client_map": {

    },
    "dot11.device.num_associated_clients": 0,
    "dot11.device.client_disconnects": 0,
    "dot11.device.last_sequence": 0,
    "dot11.device.bss_timestamp": 0,
    "dot11.device.num_fragments": 0,
    "dot11.device.num_retries": 0,
    "dot11.device.datasize": 0,
    "dot11.device.datasize_retry": 0,
    "dot11.device.last_probed_ssid_csum": 0,
    "dot11.device.last_beaconed_ssid": "LincolnFES-WiFi",
    "dot11.device.last_beaconed_ssid_checksum": 733545801,
    "dot11.device.last_bssid": "38:D2:69:F5:B4:AF",
    "dot11.device.last_beacon_timestamp": 1559567379,
    "dot11.device.wps_m3_count": 0,
    "dot11.device.wps_m3_last": 0,
    "dot11.device.wpa_handshake_list": [

    ],
    "dot11.device.wpa_nonce_list": [

    ],
    "dot11.device.wpa_anonce_list": [

    ],
    "dot11.device.wpa_present_handshake": 0,
    "dot11.device.min_tx_power": 0,
    "dot11.device.max_tx_power": 0,
    "dot11.device.supported_channels": [

    ],
    "dot11.device.link_measurement_capable": 0,
    "dot11.device.neighbor_report_capable": 0,
    "dot11.device.extended_capabilities": [

    ],
    "dot11.device.beacon_fingerprint": 4212996422,
    "dot11.device.probe_fingerprint": 0,
    "dot11.device.response_fingerprint": 0
  }
}
4

2 回答 2

1

当您想递归遍历整个对象的字段及其内容时,您需要json_tree()

SELECT j.value
FROM devices AS d
JOIN json_tree(d.device) AS j
WHERE j.key = 'dot11.advertisedssid.ssid';

value         
--------------
SampleFES-WiFi

在包含该示例对象的固定版本的表上运行时。

于 2019-06-08T13:45:35.257 回答
0

我知道这有点老了,但 OP 似乎(在评论中)想要一个更完整的解决方案。我知道当我第一次遇到这个答案时我做到了。公认的解决方案允许您从 JSON blob 中提取一个字段,但 OP 示例中的常见用例是从该 blob 中提取多个字段。经过一番搜索,我发现一旦您意识到该对象是一个数组,该json_extract()函数就可以很好地工作。"dot11.device.advertised_ssid_map"一旦你为它提供了一个索引,他的正常查询方法就起作用了。

注意事项:

  • OP 的示例与设备表中的 Kismet 设备字段有关,因此我的示例将使用我在该表的上下文中经常需要的常见查询
  • 使用 Kismet,这些 JSON blob 中使用的键很长并且包含点,因此在 SQLite3 中指定它们的语法对于某些嵌套值来说有点麻烦
  • SQLite3 的 JSON1 扩展似乎不喜欢 JSONPath 规范中通常允许的一些通配符语法,因此需要较长的显式路径

所以这是我的解决方案:

SELECT devmac, strongest_signal, 
  json_extract(d.device, '$."dot11.device"."dot11.device.advertised_ssid_map"[0]."dot11.advertisedssid.ssid"') AS ssid,
  json_extract(d.device, '$."dot11.device"."dot11.device.advertised_ssid_map"[0]."dot11.advertisedssid.cloaked"') AS cloaked,
  json_extract(d.device, '$."kismet.device.base.signal"."kismet.common.signal.min_signal"') AS weakest_signal,
  json_extract(d.device, '$."kismet.device.base.channel"') AS channel,
  json_extract(d.device, '$."dot11.device"."dot11.device.num_associated_clients"') AS clientCnt,
  json_extract(d.device, '$."kismet.device.base.crypt"') AS crypt,
  json_extract(d.device, '$."kismet.device.base.manuf"') AS manuf
FROM devices AS d
WHERE type = 'Wi-Fi AP'
;
于 2021-04-08T02:11:56.083 回答