我已经阅读了几个使用Cassandra c#driver实现手动分页的链接。
链接提及:
Backward paging in cassandra c# driver
https://datastax.github.io/csharp-driver/features/paging/
我的要求:
我正在尝试获取表格中所有不同分区键的列表,这个表格太大了。
由于大小,Cassandra db在检索它们或首次执行查询时会抛出错误。现在假设在获取100000个不同的分区键后它失败了,我将使用Cassandra c#driver提供的分页状态。
现在我在未能记录文件之前保存最后一个可用的页面状态,并再次使用它以从失败的地方继续。
我使用以下方法将分页状态保存到日志文件中:
Encoding.ASCII.GetString(pagingState);
使用以下方法检索表单日志文件:
Encoding.ASCII.GetBytes(pagingState);
但是当我将它传递给 .SetPagingState(pagingState)并执行查询时,它会抛出异常,如:
java.lang.IllegalStateException:无法调用hasNext()直到 之前的迭代器已被完全消耗
我在保存到文件之前和从文件中检索之后比较逐字节数组字节。字节数组中的几个值不同。 我尝试使用UIF8编码,但没有用。
注意: 当我在没有转换的情况下传递字节数组时,它的工作正常。我的意思是下面的条件代码完美无缺。
if (pagingState != null)
{
GenerateInitialLogs(pagingState);
}
完整功能:
private void BtnGetPrimaryKeys_Click(object sender, EventArgs e)
{
string fileContent = File.ReadAllText("D:/Logs/log.txt");
if(fileContent.Length > 0)
{
GenerateInitialLogs(Encoding.ASCII.GetBytes(fileContent));
}
else
{
GenerateInitialLogs(null);
}
}
private void Log(byte[] pagingState)
{
File.WriteAllText("D:/Logs/log.txt", Encoding.ASCII.GetString(pagingState));
}
private int GenerateInitialLogs(byte[] pagingState)
{
try
{
RowSet rowSet = BLL.SelectDistinctPrimaryKeys(pagingState);
List<PrimaryKey> distinctPrimaryKeys = new List<PrimaryKey>();
foreach (Row row in rowSet)
{
if (rowSet.PagingState != null) { pagingState = new byte[rowSet.PagingState.Length]; }
pagingState = rowSet.PagingState;
}
Log(pagingState)
if (pagingState != null)
{
GenerateInitialLogs(pagingState);
}
}
catch(Exception ex)
{
throw ex;
}
}
public static RowSet SelectDistinctPrimaryKeysFromTagReadings(byte[] pagingState)
{
try
{
// will execute on continuing after failing in between.
if (pagingState != null)
{
PreparedStatement preparedStatement = BLL.currentSession.Prepare("SELECT DISTINCT \"Url\",\"Id\" FROM \"Readings\" ");
BoundStatement boundStatement = preparedStatement.Bind();
IStatement istatement = boundStatement.SetAutoPage(false).SetPageSize(1000).SetPagingState(pagingState);
return BLL.currentSession.Execute(istatement);
}
else
{
PreparedStatement preparedStatement = BLL.currentSession.Prepare("SELECT DISTINCT \"Url\",\"Id\" FROM \"Readings\" ");
BoundStatement boundStatement = preparedStatement.Bind();
IStatement istatement = boundStatement.SetAutoPage(false).SetPageSize(1000);
return BLL.currentSession.Execute(istatement);
}
}
catch (Exception ex)
{
throw ex;
}
}
答案 0 :(得分:2)
我没想到这个解决方案。它由Jorge Bay Gondra(datastax的员工)完成。
原始回答:
https://groups.google.com/a/lists.datastax.com/forum/#!topic/csharp-driver-user/4XWTXZC-hyI
<强>解决方案:强>
无法将它们转换为ASCII或UIF8或任何编码,因为它们不代表文本。
使用这些函数将字节数组转换为十六进制,反之亦然。
public static string ByteArrayToHexaDecimalString(byte[] bytes)
{
StringBuilder stringBuilder = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes) { stringBuilder.AppendFormat("{0:x2}", b); }
return stringBuilder.ToString();
}
public static byte[] HexaDecimalStringToByteArray(String hexaDecimalString)
{
int NumberChars = hexaDecimalString.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hexaDecimalString.Substring(i, 2), 16);
}
return bytes;
}
答案 1 :(得分:0)
我还发现Encoding.UTF8.GetString和GetBytes并非在所有情况下都起作用,尽管在某些情况下也可以,但是发现Convert.ToBase64String和相反的方法可以正常工作。
public static string ConvertPagingStateToString(byte[] pagingState)
=> Convert.ToBase64String(pagingState);
public static byte[] ConvertStringToPagingState(string pagingStateString)
=> Convert.FromBase64String(pagingStateString);