【问题标题】:BigQuery, is there a way to search the whole db for a string?BigQuery,有没有办法在整个数据库中搜索字符串?
【发布时间】:2021-03-19 02:52:57
【问题描述】:

我有一个需要在数据库中找到的数据,例如'dsfsdfsads'。但是,有 100 多个表和视图可供搜索。我发现为其他数据库编写的许多查询可以在数据库中找到特定字符串。示例帖子如下。但是,我认为 BigQuery 不一样。我发现了这个问题:Is it possible to do a full text search in all tables in BigQuery?,但这篇文章感觉不完整,答案中提供的 2 个链接没有回答我的问题。

能够找到特定字符串的其他数据库查询示例:

Find a string by searching all tables in SQL Server Management Studio 2008

Search all tables, all columns for a specific value SQL Server

How do I search an SQL Server database for a string?

【问题讨论】:

  • BigQuery 专为大规模数据集而设计,它是一个可扩展到 PB 级的数据湖。你想要完成的事情是不可行的。

标签: google-bigquery full-text-search


【解决方案1】:

我不确定为什么不适合您使用 wildcard table 搜索您的数据库,就像您提到的帖子中一样。因为我已经运行了这个示例查询来搜索一个公共数据集,它工作得很好。

SELECT *
FROM `bigquery-public-data.baseball.*` b
WHERE REGEXP_CONTAINS(TO_JSON_STRING(b), r'Cubs')

我想这是因为其中一个限制是通配符表功能不支持视图。
你有很多吗?

在这种情况下,您可以仅将通配符用于您的表,并使用 _TABLE_SUFFIX 或不太通用的通配符(这取决于您的视图名称)过滤掉视图。
一般来说,对于通配符表,使用 _TABLE_SUFFIX 可以大大减少扫描的字节数,从而降低运行查询的成本。因此,如果您怀疑某些表包含的字符串比其他表多,也可以使用它。

对于视图(或整个数据集),您可以:
• 通过使用libraries 之一和Python 中的multiprocessing 等多处理模块调用BigQuery API 进行迭代。
• 通过从 bash 脚本调用 REST API 进行迭代。
• 使用 bash 脚本中的 bq command 进行迭代。

如果您在编程部分遇到问题,请发布一个新问题并在此处添加链接。

编辑:

这里有两个示例(bash 和 python)。我尝试了这两种方法,它们都有效,但当然欢迎任何有助于改进的 cmets。

Python:

  1. 安装包
pip install --upgrade google-cloud-bigquery
pip install multiprocess
  1. 创建filename.py。更改YOUR_PROJECT_IDYOUR_DATASET

from google.cloud import bigquery
import multiprocessing

def search(dataset_id):
    """
    Lists and filters your dataset to keep only views
    """
    client = bigquery.Client()
    
    tables = client.list_tables(dataset_id)
    views = []
    for table in tables:
        if table.table_type == 'VIEW':
            views.append(table.table_id)
    return views

def query(dataset_id, view):
    """
    Searches for the string in your views and prints the first one it finds.
    You can change or remove 'LIMIT 1' if needed.
    """
    client = bigquery.Client()
    query_job = client.query(
        """
        SELECT *
        FROM {}.{} b
        WHERE REGEXP_CONTAINS(TO_JSON_STRING(b), r"true")
        LIMIT 1
        """.format(dataset_id, view)
   )

    results = query_job.result()  # Waits for job to complete.
    for row in results:
        print(row)

if __name__ == '__main__':
    # TODO: Set dataset_id to the ID of the dataset that contains the tables you are listing.
    dataset_id = 'YOUR_PROJECT_ID.YOUR_DATASET'
    views = search(dataset_id)

    processes = []
    for i in views:
        p = multiprocessing.Process(target=query, args=(dataset_id, i))
        p.start()
        processes.append(p)
    for process in processes:
        process.join()

运行python filename.py


重击:

  1. 安装jq(json解析器)并测试
sudo apt-get install jq

测试

echo '{ "name":"John", "age":31, "city":"New York" }' | jq .

输出:

{
  "name": "John",
  "age": 31,
  "city": "New York"
}

Reference

  1. 创建filename.sh。更改YOUR_PROJECT_IDYOUR_DATASET
#!/bin/bash
FILES="bq ls --format prettyjson YOUR_DATASET"
RESULTS=$(eval $FILES)
DETAILS=$(echo "${RESULTS}" | jq -c '.[]')
for d in $DETAILS
do
        ID=$(echo $d | jq -r .tableReference.tableId)
        table_type=$(echo $d | jq -r '.type')
        if [[ $table_type == "VIEW" ]]
          then
                bq query --use_legacy_sql=false \
                'SELECT *
                FROM
                `YOUR_PROJECT_ID`.YOUR_DATASET.'$ID' b
                WHERE REGEXP_CONTAINS(TO_JSON_STRING(b), r"true")
                LIMIT 1'
          fi

done

运行bash filename.sh

【讨论】:

  • 我的问题是我需要查找的数据包含在视图中。这些表只是查找表,而动态数据当前存储在视图中。我肯定会创建一个新问题并在形成后发布,因为我还不熟悉您列出的任何建议。非常感谢您的帮助。
  • @WouldLiketoKnowMore,我已经用两个编程选项编辑了我的答案供您尝试。希望这会有所帮助。
  • 我花了一点时间才能够使用 python 脚本运行它,安全问题正在减慢我运行它的能力。我查看了它返回的一个条目,我发现它可以正常工作以找到该字符串。我对 Python 不是很熟悉,但是有没有办法只返回该条目所在的表/视图? IE。而不是 for row in results: print(row) 有没有办法为 row in results: print(view)
  • 代替打印(行),您可以使用以下行来打印有关数据集和找到字符串的视图的信息。以下代码行有效,因为 dataset_id 和视图变量都在函数的范围内。 print(f"在数据集中找到字符串:{dataset_id},在视图中:{view}")
猜你喜欢
  • 2018-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 2011-05-19
  • 1970-01-01
相关资源
最近更新 更多