根据:https://cloud.google.com/datastore/docs/concepts/entities#embedded_entity
在嵌入实体上设置
excludeFromIndexes: true
应将其及其属性从索引中删除,因此应允许该嵌入实体的属性大于 1500 字节。
我正在尝试编写一个嵌入实体,该实体的某些属性超过 1500 字节,但出现错误:
“Error: The value of property “additionalAttributes” is longer than 1500 bytes. at /node_modules/grpc/src/node/src/client.js:434:17"
即使我在嵌入实体上设置
excludeFromIndexes: true
(并且我可以在云控制台中看到嵌入实体已正确添加而无需索引)。
我发现存在一个已知问题:https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1916。虽然我没有看到任何修复或解决方法
关于导致此问题的原因以及如何修复/解决方法有什么建议吗?
我的问题/问题确实是这个: https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1916
答案/解决方案是通过此 PR 的固定版本https://github.com/GoogleCloudPlatform/google-cloud-node/pull/2497
解决方法是至少为需要支持超过 1500 字节的属性设置
excludeFromIndexes=true
。嵌入实体的 JSON 应如下所示。请注意 text
属性,我们在其中显式设置 excludeFromIndexes
。
{
"properties": {
"date": {
"timestampValue": "2017-06-05T18:53:23.106Z"
},
"text": {
"stringValue": "long text that exceeds 1500 bytes",
"excludeFromIndexes": true
}
}
}
我正在使用此修复程序对除其中三个属性之外的所有属性递归设置 {excludeFromIndexes: false}。在将属性发送到数据存储区之前,会调用方法entity.entityToEntityProto,但前提是您的entity.data是一个对象(也可以传递一个数组)。
您可以将此脚本包含在节点中的任何位置,最好是在启动数据存储之前。它将覆盖entity.entityToEntityProto方法。
const INCLUDE_ATTRIBUTES = ['_index','_audit','_unique'];
function entitySetIndexes(properties, path){
for(let key in properties){
let keypath = (path ? path+'.' : '') + key
, prop = properties[key];
if(prop.entityValue)
entitySetIndexes(prop.entityValue.properties, keypath);
else if(prop.arrayValue)
prop.arrayValue.values.forEach(item=>{
if(item.entityValue)
entitySetIndexes(item.entityValue.properties, keypath)
});
// excludeFromIndex cannot be set on arrays, they're always indexed
if(!prop.arrayValue)
prop.excludeFromIndexes = INCLUDE_ATTRIBUTES.indexOf(keypath) === -1;
}
}
const entity = require('@google-cloud/datastore/src/entity.js')
, entityToEntityProto = entity.entityToEntityProto;
entity.entityToEntityProto = function(entityObject){
entityObject = entityToEntityProto(entityObject);
entitySetIndexes(entityObject.properties);
return entityObject;
}
因此,请确保使用 {data:{attribute:'value'}, key:...} 保存实体。如果要索引深层属性,请指定它们以点分隔,忽略数组。 我正在使用 @google-cloud/datastore v1.1.0 中的脚本。
最简单的方法是添加
@Unindexed
注释,它将删除该属性的索引并允许您插入超过 1500 字节的字符串属性。
如果您使用 Go,则可以执行此操作:
type Whatever struct {
Id string
LongStuff string `datastore:",noindex"`}
添加
datastore:",noindex"
就可以了。