Có thể ĐẶT HÀNG kết quả bằng truy vấn hoặc quét trong DynamoDB không?


83

Có thể ĐẶT HÀNG kết quả bằng Truy vấn hoặc Quét API trong DynamoDB không?

Tôi cần biết liệu DynamoDB có thứ gì đó giống như [ORDER BY 'field'] từ các truy vấn SQL không?

Cảm ơn.

Câu trả lời:


42

Tuy nhiên, không rõ ràng, thứ tự rõ ràng là cần thiết cho nhiều trường hợp sử dụng trong thế giới thực và có thể được mô hình hóa bằng Khóa chính loại băm và loại phạm vi cho phù hợp:

Trong trường hợp này, khóa chính được tạo bởi hai thuộc tính. Thuộc tính đầu tiên là thuộc tính băm và thuộc tính thứ hai là thuộc tính phạm vi. Amazon DynamoDB xây dựng chỉ mục băm không theo thứ tự trên thuộc tính khóa chính băm và chỉ mục phạm vi được sắp xếp trên thuộc tính khóa chính phạm vi . [nhấn mạnh của tôi]

Sau đó, bạn có thể sử dụng chỉ mục phạm vi này để tùy chọn yêu cầu các mục thông qua tham số RangeKeyCondition của API truy vấn và chỉ định chuyển tiếp tới hoặc lùi của chỉ mục (tức là hướng sắp xếp) thông qua tham số ScanIndexForward .

Cập nhật: Bạn có thể sắp xếp theo một thuộc tính có chỉ mục phụ cục bộ theo cách tương tự.


18
Tham số ScanIndexForward dường như chỉ áp dụng cho Truy vấn , không phải Quét đúng không? Làm thế nào để trả về một danh sách được phân trang theo thứ tự của tất cả các mục trong một bảng bằng cách sử dụng Truy vấn? Quét dường như là cách để trả về "*", nhưng nó dường như không có tham số để sắp xếp kết quả.
case2000,

Tôi chưa sử dụng tính năng này, chỉ đọc về nó, nhưng Truy vấn hỗ trợ chỉ định Giới hạn , để giới hạn số lượng kết quả nhận được và nếu có nhiều mục phù hợp với truy vấn của bạn khi đạt đến giới hạn, bạn sẽ nhận được LastEvalonedKey có thể được sử dụng để thực hiện một truy vấn khác và tiếp tục truy xuất kết quả.
fernio

1
Gotcha quan trọng: kết quả trả về sẽ không thực sự được sắp xếp. Việc phân loại chỉ có tác dụng nếu bạn áp dụng giá trị 'Giới hạn' hoặc số lượng mục vượt quá giới hạn tra cứu 1MB. Ví dụ: bạn có thể có 5 bản ghi, với khóa phân vùng 'p1' và các khóa sắp xếp: ['b', 'd', 'a', 'c', 'e']. Nếu bạn thực hiện một truy vấn chỉ cho 'p1', bạn sẽ nhận được ['b', 'd', 'a', 'c', 'e']. Nhưng nếu bạn chỉ định Giới hạn là 2, nó sẽ trả về ['b', 'a']
jameslol 22/02/19

29

Bạn có thể sử dụng phím sắp xếp và áp dụng tham số ScanIndexForward trong một truy vấn để sắp xếp theo thứ tự tăng dần hoặc giảm dần. Ở đây tôi giới hạn các mục trả lại là 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
Vấn đề là nếu bạn muốn trả lại tất cả các mục. Về cơ bản, điều đó có nghĩa là bạn phải tạo một cột giả mới, gán cùng một giá trị trong đó cho tất cả các hàng, tạo GSI trên cột đó và gọi truy vấn thay vì quét.
JHH

Điều gì sẽ xảy ra nếu tôi muốn quay lại dựa trên một số trường không phải khóa? như trường số create_on
Yusuf

Sau đó, bạn có thể muốn lấy tất cả các bản ghi và sau đó lọc những bản ghi đó bằng javascript hoặc tương tự. DynamoDB về cơ bản là một kho khóa-giá trị với chức năng hạn chế. Nhưng rất nhanh khi bạn có thể sử dụng (các) khóa.
kometen

7

Sử dụng ScanIndexForward (đúng cho tăng dần và sai cho giảm dần) và cũng có thể giới hạn kết quả bằng cách sử dụng giá trị setLimit của Biểu thức truy vấn.

Vui lòng tìm mã bên dưới nơi đã sử dụng QueryPage để tìm một bản ghi.

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());
    }
}

Sử dụng ScanIndexForward (đúng đối với tăng dần và sai cho giảm dần)
Abhay JOHRI

2

Một tùy chọn khác sẽ giải quyết vấn đề là

  1. Xác định chỉ mục phụ cục bộ với khóa băm "bình thường" cũng là khóa băm của LSI
  2. Xác định trường bạn muốn sắp xếp là "Khóa sắp xếp" của LSI
  3. Truy vấn LSI và đặt thứ tự như mong muốn (xem ở trên)

Điều này sẽ cho phép sắp xếp bất kỳ giá trị nào trong bảng của bạn theo yêu cầu. Đó là một cách rất hiệu quả để tìm các mục xếp hạng cao nhất trong bảng của bạn mà không cần phải lấy toàn bộ truy vấn và lọc nó sau đó.


Gì ở trên? Nếu băm thông thường là một unorderd cho id được tạo sắp xếp thì việc bao gồm nó dường như không hoạt động. Tui bỏ lỡ điều gì vậy?
Samantha Atkins

1

Nếu bạn đang sử dụng boto2 và bạn có khóa sắp xếp trên một trong các cột trong bảng của mình, bạn có thể sắp xếp những gì bạn truy xuất theo thứ tự hoặc theo thứ tự ngược lại bằng cách nói:

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

Nếu bạn đang sử dụng boto3 và bạn có khóa sắp xếp trên cột mà bạn muốn sắp xếp kết quả, bạn có thể sắp xếp dữ liệu bạn truy xuất bằng cách nói:

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

Hãy nhớ trong boto3 nếu ScanIndexForward là true, DynamoDB trả về kết quả theo thứ tự chúng được lưu trữ (theo giá trị khóa sắp xếp). Đây là hành vi mặc định. Nếu ScanIndexForward là false, DynamoDB sẽ đọc kết quả theo thứ tự ngược lại bằng cách sắp xếp giá trị khóa, sau đó trả về kết quả cho máy khách.


0

Nếu bảng đã tồn tại thì hãy thêm GSI (Chỉ mục phụ toàn cầu) vào thuộc tính bạn muốn cho bảng và sử dụng Truy vấn chứ không phải Quét. Nếu bạn sắp tạo bảng thì bạn có thể thêm LSI (Local Secondary Index) vào thuộc tính bạn muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.