5

我正在尝试从 s3-select 中的 json 数据中查询数据。

   {
    person = [
    {
            "Id": 1,
            "Name": "Anshu",
            "Address": "Templestowe",
            "Car": "Jeep"
    }
    {
            "Id": 2,
            "Name": "Ben Mostafa",
            "Address": "Las Vegas",
            "Car": "Mustang"
    }
    {
                    "Id": 3,
                    "Name": "Rohan Wood",
                    "Address": "Wooddon",
                    "Car": "VW"
    }
]
}

QUERY = "select * from S3Object s"
QUERY = "select s.person from S3Object s"
QUERY = "select s.person[0] from S3Object s"
QUERY = "select s.person[0].Name from S3Object s"

所有这些查询都可以正常工作并根据需要返回相应的对象,但是当我尝试搜索名称/汽车上的数据时,它不起作用。

QUERY = "select * from S3Object s where s.person.Name = \"Anshu\" "

错误:com.amazonaws.services.s3.model.AmazonS3Exception:第 1 行第 32 列的列索引无效。

s3-select online 上相关内容不多。想知道我们是否可以查询字段名称!文档中没有提供带有 s3-select 的 where 子句的选择查询示例

4

3 回答 3

10

我在任何 AWS 文档中都找不到这个,但我只是在玩耍并发现了一种有效的语法:

QUERY = "select * from S3Object s where 'Anshu' in s.person[*].Name"

基于一些推论:

  1. 我知道当 tags 属性是一个字符串数组时,像 WHERE ('blah' in s.tags) 这样的语法会起作用。
  2. AWS 文档还说,当 # 是有效的索引/数字时,s.person[#] 应该可以工作。基于此,我发现在方括号之间使用星号 (*),如 s.person[*].Name,也可以。这是在对 s.Person[]、s.Person[#]、s.Person[?] 等各种语法进行失败测试之后...

用 Python 和 Boto3 证明:

import boto3

S3_BUCKET = 'your-bucket-name'

s3 = boto3.client('s3')

r = s3.select_object_content(
        Bucket=S3_BUCKET,
        Key='your-file-name.json',
        ExpressionType='SQL',
        Expression="select * from s3object s where 'Anshu' in s.person[*].Name",
        InputSerialization={'JSON': {"Type": "Lines"}},
        OutputSerialization={'JSON': {}}
)

for event in r['Payload']:
    if 'Records' in event:
        records = event['Records']['Payload'].decode('utf-8')
        print(records)

很奇怪,我知道。请记住在 ~/.aws/credentials 文件中设置 [default] 凭据。

于 2018-06-22T01:36:18.950 回答
3

阅读 AWS 文档后,我发现以下 SQL 工作正常。

select * from S3Object[*].person[*] as p where p.Name='Anshu'

此 SQL 将为您提供所有名为“Anshu”的人,例如:

{
    "Id": 1,
    "Name": "Anshu",
    "Address": "Templestowe",
    "Car": "Jeep"
}

当您看到[*]时,它表示一个 json 数组。

Amazon S3 Select 始终将 JSON 文档视为根级别值的数组,因此我们S3Object[*]在 SQL 中使用。而personvalue是一个数组,所以我们person[*]在SQL中使用。

于 2019-01-09T13:24:39.207 回答
1

你不能那样做。您需要稍微“扁平化”您的 JSON,使其看起来像这样:

{
person: {
        "Id": 1,
        "Name": "Anshu",
        "Address": "Templestowe",
        "Car": "Jeep"
    }
}
{ 
person: {
        "Id": 2,
        "Name": "Ben Mostafa",
        "Address": "Las Vegas",
        "Car": "Mustang"
    }
}
{   
person:{
        "Id": 3,
        "Name": "Rohan Wood",
        "Address": "Wooddon",
        "Car": "VW"
    }
}

下面的查询将按预期工作

select * from s3object s where s.person.name= 'Anshu'

于 2018-06-14T13:05:19.073 回答