如何允许在 cassandra 中使用 java datastax 进行过滤

Posted

技术标签:

【中文标题】如何允许在 cassandra 中使用 java datastax 进行过滤【英文标题】:how to allow filter in cassandra with java datastax 【发布时间】:2019-10-30 10:13:11 【问题描述】:
I created a table and two indexes on it i am not able to do filter query from my spring application 

首先我创建了表

CREATE TABLE keyspace.favourite_setting (
id uuid,
user_name text,
filter_name text,
columns LIST<FROZEN<columns_def>>,
filters text,
PRIMARY KEY (id)

);

第二个我添加了两个索引

CREATE INDEX IF NOT EXISTS user_name_index ON keyspace.favourite_setting (user_name)
CREATE INDEX IF NOT EXISTS filter_name_index ON keyspace.favourite_setting (filter_name);

然后我正在尝试过滤显示错误你必须允许过滤虽然我已经这样做了...

我的饰品

@Accessor
 public interface FavouriteSettingAccessor 


@Query("select * from favourite_setting where user_name =:userName allow filtering  " )
Result<FavouriteSetting> getAllByUserName(@Param("userName") String userName );

      

我的服务实现

@Override
public List<FavouriteSetting> getAllFilterNames(String userName) throws  Exception 

    session = cassandraFactory.getDataSource();


    favouriteSettingAccessor =
            new MappingManager(session).createAccessor(FavouriteSettingAccessor.class);


    return favouriteSettingAccessor.getAllByUserName(userName).all();

我最喜欢的设置模式

@Table(keyspace = "keyspace", name = "favourite_setting")
public class FavouriteSetting 

@PartitionKey
@Column(name = "id")
private UUID id;

@Column(name = "user_name")
private String userName;

@Column(name = "filter_name")
private String filterName;

@Column(name = "columns")
private List<ColumnsDef> columns;

@Column(name = "filters")
private String filters;

 public FavouriteSetting(UUID id, String userName, String filterName, 
 List<ColumnsDef> columns, String filters) 
    this.id = id;
    this.userName = userName;
    this.filterName = filterName;
    this.columns = columns;
    this.filters = filters;


public FavouriteSetting() 


public UUID getId() 
    return id;


public void setId(UUID id) 
    this.id = id;


public String getFilterName() 
    return filterName;


public void setFilterName(String filterName) 
    this.filterName = filterName;


public String getUserName() 
    return userName;


public void setUserName(String userName) 
    this.userName = userName;


public List<ColumnsDef> getColumns() 
    return columns;


public void setColumns(List<ColumnsDef> columns) 
    this.columns = columns;


public String getFilters() 
    return filters;


public void setFilters(String filters) 
    this.filters = filters;

无法执行此查询,因为它可能涉及数据过滤,因此可能具有不可预测的性能。如果您想在性能不可预测的情况下执行此查询,请使用 ALLOW FILTERING

【问题讨论】:

【参考方案1】:

查询

@Query("select * from favourite_setting where user_name =:userName ... " )

userName 不是主键的一部分,您可以将其设置为集群键。有关更多信息,您可以查看here 或here。

请注意,没有用于添加集群键 you will need to recreate the table 的 alter 语句:

CREATE TABLE keyspace.favourite_setting (
id uuid,
user_name text,
filter_name text,
columns LIST<FROZEN<columns_def>>,
filters text,
PRIMARY KEY (id, username)

为用户名列创建的索引被认为是索引的反模式之一,因为它被认为是唯一的(因此,它将具有高基数);你可以找到更多关于为什么这是一个问题的信息here

allow filtering 不应该被使用,正如 here you should resist the urge to just add ALLOW FILTERING to it. You should think about your data, your model and what you are trying to do. 解释的那样

【讨论】:

我只是尝试添加集群键,但相同原因:java.util.concurrent.ExecutionException:com.datastax.driver.core.exceptions.InvalidQueryException:无法执行此查询,因为它可能涉及数据过滤,因此可能具有不可预测的性能。如果您想在性能不可预测的情况下执行此查询,请使用 ALLOW FILTERING【参考方案2】:

现在可以通过添加 user_name 作为集群键并添加到查询的末尾 ALLOW FILTERING .. 谢谢:)

【讨论】:

以上是关于如何允许在 cassandra 中使用 java datastax 进行过滤的主要内容,如果未能解决你的问题,请参考以下文章

Cassandra 4.0 使用 java 驱动程序进行多选

Cassandra Stess 工具 -Err:Application 不允许任意参数:write,yaml

如何在 Java 中的 Cassandra 中注释/使用复合分区键?

在 Cassandra 中如何通过多个过滤器选择行?

Cassandra 允许在 C# 中进行过滤

当有大约 100 万条记录时,如何在 Java 中比较 Hive 和 Cassandra 数据