Indexing 如何有效地对cassandra中的两列进行范围查询?

Indexing 如何有效地对cassandra中的两列进行范围查询?,indexing,cassandra,range,Indexing,Cassandra,Range,我想在Cassandra的ColumnFamily中保存数百万个位置,然后对这些数据进行范围查询 例如: 属性:位置名称、纬度、经度 查询:从ColumnFamily中选择LocationName,其中latitute>10,latitude30和经度,这取决于查询中所需的粒度以及该粒度的可变性,处理此问题的一种方法是将地图分割成网格,其中所有位置都位于具有定义的纬度/经度边界框的网格正方形内。然后,您可以使用如下表示形式对网格正方形ID进行初始查询,然后查询这些正方形内的位置: GridSqu

我想在Cassandra的ColumnFamily中保存数百万个位置,然后对这些数据进行范围查询

例如:

属性:位置名称、纬度、经度
查询:从ColumnFamily中选择LocationName,其中latitute>10,latitude30和经度,这取决于查询中所需的粒度以及该粒度的可变性,处理此问题的一种方法是将地图分割成网格,其中所有位置都位于具有定义的纬度/经度边界框的网格正方形内。然后,您可以使用如下表示形式对网格正方形ID进行初始查询,然后查询这些正方形内的位置:

GridSquareLat {
  key: [very_coarse_lat_value] {
    [square_lat_boundary]:[GridSquareIDList]
    [square_lat_boundary]:[GridSquareIDList]
  }
  ...
}

GridSquareLon {
  key: [very_coarse_lon_value] {
    [square_lon_boundary]:[GridSquareIDList]
    [square_lon_boundary]:[GridSquareIDList]
  }
  ...
}

Location {
  key: [locationID] {
    GridSquareID: [GridSquareID]  <-- put a secondary index on this col
    Lat: [exact_lat]
    Lon: [exact_lon]
    ...
  }
  ...
}
然后,您可以为Cassandra提供表示粗粒度lat/Lon值的GridSquareLat/Lon键,以及一个列切片范围,该范围将使返回的列仅限于边界内的那些正方形。您将得到两个列表,一个是lat的网格方形ID,另一个是lon。这些列表的交点将是您范围内的网格正方形


要获得这些方格中的位置,请查询位置CF,使用二级索引对GridSquareID进行过滤,只要您的总方格数合理,这将是有效的。现在,您有了一个大小合理的位置列表,只有几个非常有效的查询,您可以轻松地将它们减少到应用程序中的精确列表中。

根据您在查询中需要的粒度以及该粒度的可变性,处理此问题的一种方法是将地图分割成网格,其中,所有位置都位于具有定义的纬度/经度边界框的网格正方形内。然后,您可以使用如下表示形式对网格正方形ID进行初始查询,然后查询这些正方形内的位置:

GridSquareLat {
  key: [very_coarse_lat_value] {
    [square_lat_boundary]:[GridSquareIDList]
    [square_lat_boundary]:[GridSquareIDList]
  }
  ...
}

GridSquareLon {
  key: [very_coarse_lon_value] {
    [square_lon_boundary]:[GridSquareIDList]
    [square_lon_boundary]:[GridSquareIDList]
  }
  ...
}

Location {
  key: [locationID] {
    GridSquareID: [GridSquareID]  <-- put a secondary index on this col
    Lat: [exact_lat]
    Lon: [exact_lon]
    ...
  }
  ...
}
然后,您可以为Cassandra提供表示粗粒度lat/Lon值的GridSquareLat/Lon键,以及一个列切片范围,该范围将使返回的列仅限于边界内的那些正方形。您将得到两个列表,一个是lat的网格方形ID,另一个是lon。这些列表的交点将是您范围内的网格正方形


要获得这些方格中的位置,请查询位置CF,使用二级索引对GridSquareID进行过滤,只要您的总方格数合理,这将是有效的。现在,您有一个大小合理的位置列表,只有几个非常有效的查询,您可以轻松地将它们减少到应用程序中的精确列表中。

让我们假设您将成长为亿万富翁,我将在下文中处理数百万个案例。如果您在cassandraor上使用类似PlayOrm的东西,或者您可以自己来做这件事,而不是使用PlayOrm,那么您需要用一些东西进行分区。假设您选择按经度分区,因此>=20和<30之间的任何内容都在分区20中,而>=30和<40之间的任何内容都在分区30中。然后在PlayOrm中,您使用它的可伸缩SQL只编写与您编写的相同的查询,但您需要查询适当的分区,在某些情况下,这些分区可能是多个分区,除非您限制结果集的大小

在PlayOrm或您的数据模型中,看起来不需要其他表

Location {
  key: [locationID] {
    LonBottom: [partitionKey]
    Lat: [exact_lat] <- @NoSqlIndexed
    Lon: [exact_lon] <- @NoSqlIndexed
    ...
  }
  ...
}

其中32和33是经度,行键指向位置。

让我们假设您将成长为亿万富翁,我将在下文中处理百万案例。如果您在cassandraor上使用类似PlayOrm的东西,或者您可以自己来做这件事,而不是使用PlayOrm,那么您需要用一些东西进行分区。假设您选择按经度分区,因此>=20和<30之间的任何内容都在分区20中,而>=30和<40之间的任何内容都在分区30中。然后在PlayOrm中,您使用它的可伸缩SQL只编写与您编写的相同的查询,但您需要查询适当的分区,在某些情况下,这些分区可能是多个分区,除非您限制结果集的大小

在PlayOrm或您的数据模型中,看起来不需要其他表

Location {
  key: [locationID] {
    LonBottom: [partitionKey]
    Lat: [exact_lat] <- @NoSqlIndexed
    Lon: [exact_lon] <- @NoSqlIndexed
    ...
  }
  ...
}

其中32和33是经度,行键指向位置。

我认为PlayOrm没有在Lat/Lon上使用二级,因为它们的基数如此之高,效率极低。底层索引的结构是什么?我想PlayOrm没有在Lat/Lon上使用二级索引,因为它们的基数太高,效率非常低。基础指数的结构是什么?我用了一些类似的东西。这不完全是我想要的,但我用了类似的东西。这不完全是我想要的,但还行