क्या DynamoDB में क्वेरी या स्कैन के साथ ORDER परिणाम संभव है?


86

क्या DynamoDB में क्वेरी या स्कैन API के साथ ORDER परिणाम संभव है?

मुझे यह जानने की जरूरत है कि क्या SQL प्रश्नों से डायनेमोबीडी [ORDER BY 'फ़ील्ड'] जैसा कुछ है?

धन्यवाद।

जवाबों:


44

स्पष्ट रूप से नहीं, हालांकि, कई वास्तविक दुनिया के उपयोग के मामलों के लिए आदेश देने की स्पष्ट रूप से आवश्यकता है और तदनुसार हैश और रेंज प्रकार के प्राथमिक उपकरणों के द्वारा मॉडलिंग की जा सकती है :

इस मामले में, प्राथमिक कुंजी दो विशेषताओं से बनी है। पहली विशेषता हैश विशेषता है और दूसरी विशेषता सीमा विशेषता है। Amazon DynamoDB हैश प्राइमरी की एट्रीब्यूट पर अनारक्षित हैश इंडेक्स बनाता है और रेंज प्राइमरी की एट्रिब्यूट पर एक सॉर्टेड रेंज इंडेक्स[जोर मेरा]

इसके बाद आप इस रेंज इंडेक्स का उपयोग करके वैकल्पिक रूप से के माध्यम से आइटम का अनुरोध कर सकते हैं RangeKeyCondition के पैरामीटर क्वेरी API और निर्दिष्ट आगे या सूचकांक के पिछड़े ट्रेवर्सल के माध्यम से (यानी प्रकार दिशा) ScanIndexForward पैरामीटर।

अद्यतन: आप उसी तरह से स्थानीय माध्यमिक सूचकांक के साथ एक विशेषता द्वारा आदेश दे सकते हैं ।


19
ScanIndexForward परम केवल क्वेरी पर लागू होता है , स्कैन सही नहीं है? क्वेरी का उपयोग करके किसी तालिका में सभी आइटमों की क्रमबद्ध पृष्ठांकित सूची को कैसे लौटाया जाएगा? स्कैन "*" को वापस करने का तरीका प्रतीत होता है, लेकिन परिणाम के आदेश के लिए यह एक परम नहीं है।
केस २२

मैंने इस सुविधा का उपयोग नहीं किया है, केवल इसके बारे में पढ़ा है, लेकिन प्राप्त परिणामों की संख्या को कैप करने के लिए क्वेरी एक सीमा को निर्दिष्ट करने का समर्थन करती है , और अगर सीमा पार होने पर आपकी क्वेरी से मेल खाने वाले अधिक आइटम हैं, तो आप एक LastEvalookKey प्राप्त करेंगे इसका उपयोग अन्य क्वेरी करने और परिणामों को प्राप्त करने के लिए किया जा सकता है।
फ़र्नियो

1
महत्वपूर्ण गेटचा: दिए गए परिणाम वास्तव में हल नहीं होंगे। यदि आप एक 'सीमा' मान लागू करते हैं, या आइटम की संख्या 1MB लुकअप सीमा से अधिक हो जाती है, तो छंटनी केवल खेल में आती है। उदाहरण के लिए, आपके पास 5 रिकॉर्ड हो सकते हैं, जिसमें विभाजन कुंजी 'p1', और सॉर्ट कीज़: ['b', 'd', 'a', 'c', 'e']। यदि आप केवल 'p1' के लिए कोई क्वेरी करते हैं, तो आपको ['b', 'd', 'a', 'c', 'e'] प्राप्त होंगे। लेकिन यदि आप 2 की सीमा निर्दिष्ट करते हैं, तो यह ['b', 'a'
jameslol

29

आप सॉर्ट-कुंजी का उपयोग कर सकते हैं और किसी भी आरोही या अवरोही क्रम में सॉर्ट करने के लिए किसी क्वेरी में ScanIndexForward पैरामीटर को लागू कर सकते हैं । यहां मैंने आइटम को 1 पर सीमित कर दिया है।

var params = {
    TableName: 'Events',
    KeyConditionExpression: 'Organizer = :organizer',
    Limit: 1,
    ScanIndexForward: false,    // true = ascending, false = descending
    ExpressionAttributeValues: {
        ':organizer': organizer
    }
};

docClient.query(params, function(err, data) {
    if (err) {
        console.log(JSON.stringify(err, null, 2));
    } else {
        console.log(JSON.stringify(data, null, 2));
    }
});

8
समस्या यह है कि यदि आप सभी आइटम वापस करना चाहते हैं । अनिवार्य रूप से इसका मतलब है कि आपको एक नया डमी कॉलम बनाना है, इसमें समान मूल्य सभी पंक्तियों को असाइन करें, उस कॉलम पर एक जीएसआई बनाएं और स्कैन के बजाय क्वेरी कॉल करें।
जेएचएच

क्या होगा यदि मैं कुछ गैर-कुंजी क्षेत्र के आधार पर वापस लौटना चाहता हूं? like_on नंबर फ़ील्ड की तरह
यूसुफ

तब आप सभी अभिलेख प्राप्त करना चाहते हैं और फिर जावास्क्रिप्ट या इसी तरह का उपयोग करने वालों को फ़िल्टर कर सकते हैं। डायनामोबीडी मूल रूप से सीमित कार्यक्षमता के साथ एक कुंजी-मूल्य-स्टोर है। लेकिन बहुत तेज है जब आप कुंजी का उपयोग कर सकते हैं।
१२:२० बजे १२'०

7

ScanIndexForward का उपयोग करें (अवरोही के लिए सही और अवरोही के लिए सही) और क्वेरी अभिव्यक्ति के सेटलिमिट मान का उपयोग करके परिणाम को सीमित भी कर सकता है।

कृपया उस कोड के नीचे खोजें जहां एकल रिकॉर्ड खोजने के लिए QueryPage का उपयोग किया गया था।

public void fetchLatestEvents() {
    EventLogEntitySave entity = new EventLogEntitySave();
    entity.setId("1C6RR7JM0JS100037_contentManagementActionComplete");

    DynamoDBQueryExpression<EventLogEntitySave> queryExpression = new DynamoDBQueryExpression<EventLogEntitySave>().withHashKeyValues(entity);
    queryExpression.setScanIndexForward(false);
    queryExpression.withLimit(1);
    queryExpression.setLimit(1);

    List<EventLogEntitySave> result = dynamoDBMapper.queryPage(EventLogEntitySave.class, queryExpression).getResults();
    System.out.println("size of records = "+result.size() );
}

@DynamoDBTable(tableName = "PROD_EA_Test")
public class EventLogEntitySave {

        @DynamoDBHashKey
        private String id;
        private String reconciliationProcessId;
        private String vin;
        private String source;
}

public class DynamoDBConfig {
    @Bean
    public AmazonDynamoDB amazonDynamoDB() {

            String accesskey = "";
            String secretkey = "";
            //
            // creating dynamo client
            BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey);
            AmazonDynamoDB dynamo = new AmazonDynamoDBClient(credentials);
            dynamo.setRegion(Region.getRegion(Regions.US_WEST_2));
            return dynamo;
        }

    @Bean
    public DynamoDBMapper dynamoDBMapper() {
        return new DynamoDBMapper(amazonDynamoDB());
    }
}

ScanIndexForward का उपयोग करें (आरोही के लिए सच और अवरोही के लिए असत्य)
ABHAY JOHRI

2

एक अन्य विकल्प जो समस्या को हल करना चाहिए है

  1. "सामान्य" हैश कुंजी के साथ LSI की हैश कुंजी के साथ एक स्थानीय माध्यमिक सूचकांक को परिभाषित करें
  2. उस फ़ील्ड को परिभाषित करें जिसे आप LSI के "सॉर्ट की" के रूप में सॉर्ट करना चाहते हैं
  3. LSI को क्वेरी करें और ऑर्डर को वांछित के रूप में सेट करें (ऊपर देखें)

यह आवश्यकतानुसार आपकी तालिका के किसी भी मूल्य को छाँटने में सक्षम करेगा। यह पूरी क्वेरी को प्राप्त करने और फिर बाद में फ़िल्टर करने की आवश्यकता के बिना आपकी तालिका में उच्चतम रैंकिंग आइटम खोजने के लिए एक बहुत ही कुशल तरीका है।


क्या ऊपर? अगर सामान्य हैश सॉर्ट जनरेट आईडी के लिए एक अनियंत्रित है, तो यह काम करने के लिए प्रतीत नहीं होता है। क्या मैं कुछ भूल रहा हूँ?
सामन्था एटकिंस

1

यदि आप boto2 का उपयोग कर रहे हैं और आपकी तालिका में किसी एक स्तंभ पर छँटनी की कुंजी है, तो आप क्रमबद्ध रूप से कह सकते हैं कि आप क्रम में या रिवर्स ऑर्डर में क्या प्राप्त करते हैं:

result = users.query_2(
    account_type__eq='standard_user',
    reverse=True)

यदि आप boto3 का उपयोग कर रहे हैं और आपके पास उस कॉलम की सॉर्ट कुंजी है जिसे आप परिणाम के आधार पर क्रमबद्ध करना चाहते हैं, तो आप कहे गए डेटा को सॉर्ट कर सकते हैं:

result = users.query(
    KeyConditionExpression=Key('account_type').eq('standard_user'),
    ScanIndexForward=True)

Boto3 में याद रखें कि अगर ScanIndexForward सही है, तो DynamoDB उस क्रम में परिणाम लौटाता है जिसमें वे संग्रहीत होते हैं (सॉर्ट कुंजी मान द्वारा)। यह पहले गलत व्यवहार है। यदि ScanIndexForward गलत है, तो DynamoDB उल्टे क्रम में परिणामों को सॉर्ट कुंजी द्वारा पढ़ता है, और फिर क्लाइंट को परिणाम देता है।


0

यदि तालिका पहले से मौजूद है, तो तालिका के लिए इच्छित विशेषता में GSI (ग्लोबल सेकेंडरी इंडेक्स) जोड़ें और क्वेरी का उपयोग करें, स्कैन का नहीं। यदि आप तालिका बनाने वाले हैं तो आप अपनी इच्छा के अनुसार LSI (स्थानीय माध्यमिक सूचकांक) जोड़ सकते हैं।


0

मैंने कभी नहीं सोचा था कि इस तरह का एक तुच्छ कार्य डायनेमोडीबी में एक समस्या में बदल सकता है। डायनामो को कुछ बुनियादी विभाजन की आवश्यकता होती है। मैंने एक अतिरिक्त कॉलम जोड़कर डेटा ऑर्डर करने में कामयाबी हासिल की स्टेटस और फिर दोनों क्षेत्रों का उपयोग करके जीएसआई इंडेक्स बनाने में । मैं createAt फ़ील्ड द्वारा स्थिति = "सक्रिय" के साथ डेटा का आदेश देता हूं।

GSI बनाएं

{
        IndexName: "createdAt",
        KeySchema: [
            { AttributeName: "status", KeyType: "HASH" },
            { AttributeName: "createdAt", KeyType: "RANGE" }
        ],
        Projection: { ProjectionType: "ALL" },
        ProvisionedThroughput: {
          ReadCapacityUnits: N,
          WriteCapacityUnits: N
        }
      }

क्वेरी डेटा

const result = await this.dynamoClient.query({
  TableName: "my table",
  IndexName: "createdAt",
  KeyConditionExpression: "#status = :status and #createdAt > :createdAt",
  Limit: 5,
  ExpressionAttributeValues: {
    ":status": {
      "S": "active"
    },
    ":createdAt": {
      "S": "2020-12-10T15:00:00.000Z"
    }
  },
  ExpressionAttributeNames: {
    "#status": "status",
    "#createdAt": "createdAt"
  },
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.