简体   繁体   English

DynamoDB - 如何查询嵌套属性 boto3

[英]DynamoDB - How to query a nested attribute boto3

I am following the DynamoDB python tutorial.我正在关注 DynamoDB python 教程。 This step shows how to query the table based on a specific key: http://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.Python.04.html .此步骤显示如何根据特定键查询表: http : //docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.Python.04.html

Here is the code for this query:这是此查询的代码:

from __future__ import print_function # Python 2/3 compatibility
import boto3
import json
import decimal
from boto3.dynamodb.conditions import Key, Attr

# Helper class to convert a DynamoDB item to JSON.
class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, decimal.Decimal):
            return str(o)
        return super(DecimalEncoder, self).default(o)

dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000")

table = dynamodb.Table('Movies')

print("Movies from 1992 - titles A-L, with genres and lead actor")

response = table.query(
    ProjectionExpression="#yr, title, info.genres, info.actors[0]",
    ExpressionAttributeNames={ "#yr": "year" }, # Expression Attribute Names for Projection Expression only.
    KeyConditionExpression=Key('year').eq(1992) & Key('title').between('A', 'L')
)

for i in response[u'Items']:
    print(json.dumps(i, cls=DecimalEncoder))

An example response item is一个示例响应项是

{
    "title": "Juice",
    "year": "1992",
    "info": {
        "actors": [
            "Omar Epps"
        ],
        "genres": [
            "Crime",
            "Drama",
            "Thriller"
        ]
    }
}

The table has the two key attributes 'title' and 'year' as well as the nested attribute 'info'.该表具有两个关键属性“title”和“year”以及嵌套属性“info”。 What I am trying to do is query the database and filter the movies by genre, for example get all Drama movies.我想要做的是查询数据库并按流派过滤电影,例如获取所有戏剧电影。 I am not sure how to do this since the genre key is nested inside info.我不确定如何执行此操作,因为类型键嵌套在信息中。

I tried to get all the Drama movies from 1992 like this but it came up blank.我试图像这样获取 1992 年的所有剧情电影,但结果是空白。

response = table.query(
    KeyConditionExpression=Key('year').eq(1992),
    FilterExpression=Attr('info.genres').eq('Drama')
)

How do I properly filter this query with the nested info attribute?如何使用嵌套的 info 属性正确过滤此查询?

You can use contains to filter the data from List data type.您可以使用contains来过滤List数据类型中的数据。

genres -attribute stored as List inside info attribute which is a Map data type类型 -属性存储为列表中的info属性,这是一种地图数据类型

FilterExpression=Attr('info.genres').contains('Drama')

Unlike in the accepted answer, to be able to filter all the items with the attribute, you need to use scan() instead of query() .与接受的答案不同,为了能够过滤具有该属性的所有项目,您需要使用scan()而不是query() query() requires KeyCondition which is unnecessary in your case and forces you to create condition containing fe year. query()需要KeyCondition这在您的情况下是不必要的,并强制您创建包含 fe year 的条件。

Therefore所以

table.scan(FilterExpression=Attr('info.genres').contains('Drama'))

should do the job应该做这份工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM