我的GraphQL模式包括具有大型数据数组的对象,这些数据是此对象所特有的,在其他对象中找不到。
例如:
type Position {
time: Integer
latitude: Float
longitude: Float
}
type ObjectInSpaceAndTime {
name: String
positions(start: Int, end: Int): [Position]
}我对GraphQL客户端中规范化的理解是响应图将被扁平化,Position的每个实例在缓存中提取,为其创建一个唯一的键(从位置的路径,所以类似于someobject.positions.42)。这是非常消耗CPU和内存的,需要数千个值。
缓存将如下所示:
{
__ObjectInSpaceAndTime.someid: {name: 'xxx'},
__ObjectInSpaceAndTime.someid.positions.0: {time: 1221121, latitude: 0, longitude: 0},
__ObjectInSpaceAndTime.someid.positions.1: {time: 1221122, latitude: 0, longitude: 0},
// ...
}相反,我想告诉Apollo客户端不要尝试标准化这一点,只存储整个ObjectInSpaceAndTime实例及其字段,也许还有传递给字段的参数,以便具有不同属性的查询产生缓存未命中。这将大大减少apollo在处理回复时在内存中所做的工作。数据数组将从响应中反序列化一次,并且无需apollo客户端对其进行迭代即可使用。
{
__ObjectInSpaceAndTime.someid: {name: 'xxx',
positions: [ {time: 1221121, latitude: 0, longitude: 0},
{time: 1221122, latitude:0, longitude: 0},
/* ... */ ],
// ...
}使用Apollo客户端可以做到这一点吗?我找不到这样做的方法。
对于如何更好地对此“图”进行建模的建议也很受欢迎。
发布于 2019-01-23 01:25:00
到目前为止,我找到的最好的解决方案是切换到另一个缓存,即apollo-cache-hermes。Hermes将只存储他们所说的“实体”,即一个带有'id‘返回的对象(我在简化,但这是默认行为)。
我写了一个简单的基准测试工具,获取一个与12k“点”数组相关联的对象。该点的属性之一是具有用于纬度和经度的键的GPS坐标。
使用默认的apollo-inmemory缓存,我得到:
1st query (not cached)
Network time: 2358ms
Received data navDataCount=12860 Timer=3013ms Memory=82.41MB CacheEntries=25722
2nd query (cached)
Received data navDataCount=12860 Timer=19ms Memory=86.26MB CacheEntries=25722缓存处理时间: 655ms
阿波罗-赫尔墨斯:
1st query (not cached)
Network time: 2891ms
Received data navDataCount=12860 Timer=3079ms Memory=23.36MB CacheEntries=3
2nd query (cached)
Received data navDataCount=12860 Timer=51ms Memory=22.37MB CacheEntries=3缓存处理时间: 188ms
(我多次运行测试,处理时间变化不大)。
对我来说,这是一个很好的解决方案,尽管我对apollo-inmemory对第二个查询的响应速度如此之快感到惊讶。655ms对于处理如此大量的对象来说并不是一个坏的时间,而apollo-inmemory仍然是一个非常可靠的选择。
https://stackoverflow.com/questions/54307214
复制相似问题