说我在PHP中有这个数组。
$ids = [
246,
8362,
5241,
2586,
6548,
9372,
28504,
14,
5729
];
这些数组元素对应于存储桶“文章”中的项目,有时这个数组可能类似于1000个元素。
目前,我正在遍历所有这些并将数据逐个拉出。
$articles = [];
foreach($ids as $id)
{
$articles[] = Riak::get("articles.$id");
}
当ID列表变得很长时,这比我想要花费的时间更长。
是否有更快的方法从Riak存储桶中提取项目列表?我已经环顾了一下,map-reduce很有用,但显然会导致比使用顺序GET请求保存更多的开销。
答案 0 :(得分:2)
不幸的是,从Riak高效获取大量记录很困难,因为它们分散在整个群集中,必须单独检索。一些客户端库最近获得了对客户端多端获取的支持,它允许使用多个连接并行获取对象,但我认为这还没有到达PHP客户端。
使用mapreduce执行此操作将减少对数据库的调用次数,但不会导致读取仲裁,因为它只查询覆盖的一组分区。然而,Mapreduce是一种相当广泛的查询数据的方式,并且不能像直接密钥访问那样扩展或执行。
如果这是您需要执行的常见操作,则可能表明您的数据模型过于规范化,并且您可能需要进行反规范化,以便更好地支持您的应用程序及其访问模式。
究竟如何做到这一点需要了解您的数据以及您的访问和查询模式。一种方式可以是基于例如基于例如已知且可预测的密钥将多个物品存储在单个对象中。固定范围的文章ID。这将使文章的检索效率更高,因为需要阅读的对象要少得多,但在更新和插入时可能会花费更多的复杂性。
另一种选择是通过复制数据来去标准化。如果你是只需要文章中的一些信息,您就可以将这些数据存储在专门用于有效提供这些查询的单独对象中。
通常,在Riak中检索具有比您需要的更多信息的更大对象并在应用程序级别进行过滤比尝试从数据库中获取所需的记录更好。
答案 1 :(得分:1)
基于https://github.com/basho/riak-php-client PHP示例:
/**
* Retrieve JSON-encoded objects from Riak.
* @param array(int) $keys - List of the key.
* @return RiakObjects
*/
public function multiGet($keys) {
if (!$keys || !count($keys))
return array();
$query = null;
foreach ($keys as $key) {
if ($query) {
$query->add($this->getBucketName(), $key);
} else {
$query = $this->riak->add($this->getBucketName(), $key);
}
}
$results = $query->map(('function(riakObject){return [{"key":riakObject.key, "document":riakObject.values}];}'))->run();
if (!$results || !count($results)) {
return array();
}
$objects = array();
foreach ($results as $data) {
if (isset($data->key) && isset($data->document[0]->data) && !empty($data->document[0]->data)) {
$object = json_decode($data->document[0]->data, true);
if ($object) {
$objects[$data->key] = $object;
}
}
}
return $objects;
}