2015-12-22 16 views
8

Chúng tôi đang sử dụng Cassandra làm nhà sử dụng dữ liệu cho giải pháp quản lý hạm đội của chúng tôi. Chúng tôi có một chiếc bàn ở Cassandra, nơi lưu trữ các chi tiết của cuộc hành trình do chiếc xe thực hiện. Các cấu trúc bảng là như đưa ra dưới đâyLỗi Cassandra - Không thể giới hạn cột nhóm (cột trước bị giới hạn bởi quan hệ phi EQ)

CREATE TABLE journeydetails(
bucketid text, 
vehicleid text, 
starttime timestamp, 
stoptime timestamp, 
travelduration bigint, 
PRIMARY KEY (bucketid,vehicleid,starttime,travelduration) 
); 

đâu:

  1. bucketid: - chìa khóa phân vùng mà là một sự kết hợp của tháng, năm
  2. vehicleid: id -unique của xe
  3. StartTime : - thời gian bắt đầu của hành trình
  4. thời gian kết thúc: - thời gian kết thúc của hành trình
  5. độ lệch: - thời gian di chuyển trong millisecon ds

Chúng tôi muốn chạy truy vấn sau đây - được tất cả các hành trình của một chiếc xe - 1234567 giữa 2015/12/01 và 2015/12/03 có thời gian du lịch lớn hơn 30 phút

Khi tôi chạy truy vấn này:

select * from journeydetails where bucketid in('2015-12') and vehicleid in('1234567') 
    and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59' 
    and travelduration > 1800000; 

tôi nhận được kết quả này:

InvalidRequest: code=2200 [Invalid query] message="Clustering column "travelduration" 
cannot be restricted (preceding column "starttime" is restricted by a non-EQ relation) 

Có ai có đề xuất về cách khắc phục vấn đề này không?

Trả lời

15
select * from journeydetails where bucketid in('2015-12') and vehicleid in('1234567') 
    and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59' 
    and travelduration > 1800000; 

Điều đó sẽ không hoạt động. Lý do quay trở lại cách Cassandra lưu trữ dữ liệu trên đĩa. Ý tưởng với Cassandra là nó rất hiệu quả trong việc trả về một hàng duy nhất với một khóa chính xác, hoặc trả về một loạt các hàng liên tục từ đĩa.

Hàng của bạn được phân đoạn theo bucketid và sau đó được sắp xếp trên đĩa theo vehicleid, starttimetravelduration. Vì bạn đã thực hiện truy vấn phạm vi (quan hệ không phải EQ) trên starttime, bạn không thể hạn chế khóa theo sau. Điều này là do hạn chế travelduration có thể bị loại một số hàng trong điều kiện phạm vi của bạn. Điều này sẽ dẫn đến việc đọc không hiệu quả, không liên tục. Cassandra được thiết kế để bảo vệ bạn khỏi việc viết các truy vấn (như thế này), có thể có hiệu suất không thể đoán trước.

Dưới đây là hai lựa chọn:

1- Nếu bạn có thể hạn chế tất cả các cột quan trọng của bạn trước khi travelduration (với một bằng mối quan hệ), sau đó bạn có thể áp dụng một của bạn lớn hơn-hơn điều kiện:

select * from journeydetails where bucketid='2015-12' and vehicleid='1234567' 
    and starttime='2015-12-1 00:00:00' and travelduration > 1800000; 

Tất nhiên, hạn chế chính xác starttime có thể không hữu ích khủng khiếp.

2- Cách tiếp cận khác sẽ là bỏ qua hoàn toàn travelduration và sau đó truy vấn ban đầu của bạn sẽ hoạt động.

select * from journeydetails where bucketid='2015-12' and vehicleid='1234567' 
    and starttime > '2015-12-1 00:00:00' and starttime < '2015-12-3 23:59:59'; 

Thật không may, Cassandra không cung cấp mức độ linh hoạt truy vấn lớn.Nhiều người đã tìm thấy thành công bằng cách sử dụng một giải pháp như Spark (cùng với Cassandra) để đạt được cấp độ báo cáo này.

Và chỉ một lưu ý phụ, nhưng không sử dụng IN trừ khi bạn phải làm như vậy. Truy vấn với IN tương tự như sử dụng chỉ mục phụ, trong đó Cassandra phải nói chuyện với một vài nút để thỏa mãn truy vấn của bạn. Gọi nó với một món đồ có lẽ không quá lớn. Nhưng IN là một trong những thói quen RDBMS cũ mà bạn thực sự nên phá vỡ trước khi đi sâu vào Cassandra.

+0

Cảm ơn các bình luận Aron ... Tôi sẽ khám phá Spark như một sự thay thế – sam1977

Các vấn đề liên quan