J'essaie d'interroger les données des données json dans s3-select.

   {
    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"

Toutes ces requêtes fonctionnent bien et renvoie l'objet respectif comme souhaité, mais lorsque j'essaie de rechercher des données sur le nom / la voiture, cela ne fonctionne pas.

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

Erreur: com.amazonaws.services.s3.model.AmazonS3Exception: l'index de colonne à la ligne 1, colonne 32 n'est pas valide.

Il n'y a pas beaucoup de contenu connexe disponible sur s3-select en ligne. Vous vous demandez si nous pouvons interroger le nom du champ ou non! Il n'y a pas d'exemples de requête select avec clause where pour s3-select donné dans la documentation

4
yogas 14 mai 2018 à 09:18

3 réponses

Meilleure réponse

Je ne trouve cela dans aucune des documentations AWS, mais je jouais juste et j'ai découvert une syntaxe fonctionnelle:

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

Sur la base de certaines déductions:

  1. Je sais que la syntaxe comme WHERE ('blah' dans s.tags) fonctionne lorsque la propriété des tags est un tableau de chaînes.
  2. La documentation AWS indique également que la personne [#] doit fonctionner lorsque # est un index / chiffre valide. Sur cette base, j'ai découvert que l'utilisation d'étoile (*) entre crochets, comme dans s.person [*]. Name, fonctionne également. C'est après l'échec du test de diverses syntaxes telles que s.Person [], s.Person [#], s.Person [?], Etc ...

Preuve avec Python et 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)

Bizarre, je sais. N'oubliez pas de définir les informations d'identification [par défaut] dans le fichier ~ / .aws / credentials.

6
Noogen 22 juil. 2018 à 05:11

Vous ne pouvez pas le faire de cette façon. Vous devez "aplatir" un peu votre JSON pour qu'il ressemble à ceci:

{
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"
    }
}

La requête ci-dessous fonctionnera comme prévu alors

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

0
theshadog 7 juin 2019 à 12:06

Après avoir lu le document AWS, je trouve que SQL suivant fonctionne bien.

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

Ce SQL vous donnera toutes les personnes dont le nom est 'Anshu', comme:

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

Lorsque vous voyez [*], cela signifie un tableau json.

Amazon S3 Select traite toujours un document JSON comme un tableau de valeurs de niveau racine, nous utilisons donc S3Object[*] dans le SQL. Et la valeur person est un tableau, nous utilisons donc person[*] dans le SQL.

2
loic 9 janv. 2019 à 13:24