首页 > 解决方案 > 如何在 awsappsync 中对简单的 graphQL 查询进行排序?

问题描述

我需要的非常简单,在 SQL 中我会说我只需要一个 SORT ASCENDING 或 DESCENDING。

但我使用 GraphQL、AppSync、DynamoDB 和 React-Native 已经有一段时间了,但我仍然不知道如何按名称对输出列表进行排序......

我正在使用简单的场景,没有 React-Native Apollo,只有 Connect 组件。

我的输出列表:

class PlantScreenNoApollo extends React.Component {

...

    render() {
       
        return (
    
    <View style={{flex:1, flexDirection:"column", justifyContent:"flex-start"}}>
        
        <View style={{flex:1,
                  flexDirection:"row",
                  justifyContent:"center",
        }}>
            <TextInput style={styles.sTextInput}
                        onChangeText={ (text) => this._updateFilter(text) }
                        value={this.state.filter}/>
            <Ionicons name={"ios-search"} size={30} />
        </View>

        <View style={{  flex:1, 
                        flexDirection:"column",
                        justifyContent:"flex-start",
                        alignContent: "center",
                        minHeight: "70%",}}>
                        
        <Connect query={ this.state.filter!=="" ? 
                         graphqlOperation(queries.listPlants, {
                            filter: {
                                name: {
                                    contains: this.state.filter
                                }
                            }
                         })
                         :
                         graphqlOperation(queries.listPlants)
                        
        }>
            {
                ( { data: { listPlants }, loading, error } ) => {
                    
                    if(error) return (<Text>Error</Text>);
                    
                    if(loading || !listPlants) return (<ActivityIndicator />);
                    
                    return (
                    
                          <FlatList
                            data={listPlants.items}
                            renderItem={({item}) => {
                                return (
                                    <View style={{borderBottomWidth:1, borderBottomColor:"green", padding:5}}>
                                    <TouchableOpacity onPress={()=>this._onPress(item)}>
                                        <View style={styles.hcontainer}>
                                            <Image source={{uri:this.state.logoURL}}
                                                style={styles.iconImage}
                                            />
                                            <View style={styles.vcontainer}>
                                                <Text style={styles.textH3}>{item.name}</Text>
                                                <View style={styles.hcontainerflexstart}>
                                                    { item.tea &&  <Image source={{uri:this.state.teaIconURL}} style={styles.iconImageSmall} />}
                                                    { item.bath &&  <Image source={{uri:this.state.bathIconURL}} style={styles.iconImageSmall} />}
                                                    { item.insence &&  <Image source={{uri:this.state.insenceIconURL}} style={styles.iconImageSmall} />}
                                                    { item.children &&  <Image source={{uri:this.state.childrenIconURL}} style={styles.iconImageSmall} />}
                                                </View>
                                            </View>
                                            <Text style={styles.textP}>{item.description.substr(0,50) + "(...)"}</Text>
                                        </View>
                                    </TouchableOpacity>    
                                    </View>
                                );
                            }}
                            keyExtractor={(item, index) => item.id}
                        />

                    );
                    
                    
                }
            }
        </Connect>
        </View>
        <View style={{flex:1, flexDirection:"column", justifyContent:"flex-start"}}>


...

        </View>
    </View>
      );  
    };
    
}

这是我的查询描述(由模型+代码生成自动生成)

export const listPlants = `query ListPlants(
  $filter: ModelPlantFilterInput
  $limit: Int
  $nextToken: String
) {
  listPlants(filter: $filter, limit: $limit, nextToken: $nextToken) {
    items {
      id
      name
      description
      ...
    }
    nextToken
  }
}

我想要的只是按名称对扫描进行排序。

我什至尝试创建一个二级索引,但它没有改变任何东西......

有谁知道实现这一目标的最佳方法?

标签: react-nativegraphqlaws-amplifyaws-appsync

解决方案


更改您的 listPlants 解析器以执行查询而不是扫描,您可以利用 scanIndexForward 布尔值来确定是否要根据提供的索引(在您的情况下为“名称”)以升序或降序返回结果。

这将要求您在 DynamoDB 中索引 name 属性(如果它还没有的话)。

有关更多信息 - 请查看以下文档中的查询部分:

尤其是:

向前扫描索引

指定索引遍历的顺序:如果为true(默认),则按升序进行遍历;如果为 false,则按降序执行遍历。

具有相同分区键值的项目按排序键按排序顺序存储。如果排序键数据类型为数字,则结果按数字顺序存储。对于 String 类型,结果按 UTF-8 字节顺序存储。对于 Binary 类型,DynamoDB 将二进制数据的每个字节视为无符号。

如果 ScanIndexForward 为 true,则 DynamoDB 按结果存储顺序(按排序键值)返回结果。这是默认行为。如果 ScanIndexForward 为 false,则 DynamoDB 按排序键值逆序读取结果,然后将结果返回给客户端。

这是一个详细的stackoverflow答案,详细说明了这一点。


推荐阅读