如果数据存储已编入索引,则不允许超过1500字节的属性。所以,如果我有一个对象
{foo : X, bar : Y}
其中Y超过1500个字符我可以禁用单个属性的索引并通过数组存储它,因此:
[
{ name : 'foo', value: 'X'},
{ name: 'bar', value: 'Y', excludeFromIndexes: true}
]
但是,如果属性是嵌入式实体(即另一个实体的属性内的实体)的一部分,则此方法不起作用。 我该如何存储这样的东西?
{ foo : X, bar : { baz : Y } }
这不起作用:
[
{ name : 'foo', value: 'X'},
{ name: 'bar', value:
{
name: 'baz',
value: 'Y',
excludeFromIndexes: true
},
excludeFromIndexes: true}
]
这就是:
[
{ name : 'foo', value: 'X'},
{ name: 'bar', value: {'baz', 'Y' }, excludeFromIndexes: true}
]
更新: 这是一个示例代码段:
const DataStore = require('@google-cloud/datastore');
const datastore = DataStore({projectId});
const foo1 = { name : { forename: 'Dave', surname : 'Tong' }, colour : 'blue'}
const putAndGet = async data => {
return new Promise(async (resolve, reject) => {
try {
const key = await datastore.save({key: datastore.key([Kind]), data: data});
} catch (err) {
reject(err);
}
const results = [];
const query = datastore.createQuery(Kind);
query.runStream()
.on('error', (error) => {
reject(new Error(error));
})
.on('data', (entity) => {
results.push(entity);
})
.on('end', () => {
resolve(results);
});
});
}
// This will succeed
putAndGet(foo1).then(ret => {
for (var i = 0; i < ret.length; i++) {
console.log(ret[i].name.forename + " likes " + ret[i].colour);
}
const str = [];
for (var i = 0; i < 400; i++) str[i] = 'X';
const foo2 = {name: {forename: str.join('XXX'), surname: 'Tong'}, colour: 'blue'}
// This will fail
return putAndGet(foo2);
}).then(ret => {
for (var i = 0; i < ret.length; i++) {
console.log(ret[i].name.forename + " likes " + ret[i].colour);
}
}).catch(err => {
console.log(err.message);
});
答案 0 :(得分:1)
经过一些测试,我能够实现您想要的目标。我也编辑了你的问题,为了让这篇文章的未来读者更清楚,因为你引用了另一个属性&#34;的&#34; 属性部分,但这是在数据存储区为EmbeddedEntity,因此我会坚持使用该名称以获得更清晰的解释。
嵌入式实体的子属性可能超过1500字节,但您必须明确排除这些子属性,否则将显示错误。为此,您必须将每个EmbeddedEntity声明为:
{
"properties": {
"surname": {
"stringValue": "A long surname which has more than 1500B",
"excludeFromIndexes": true
},
"forename": {
"stringValue": "David"
}
}
}
但是使用NodeJS以编程方式声明"excludeFromIndexes": true
并不是太直截了当。但最后我设法解决了它。关键是save()
功能,您可以在其中声明要从索引中排除的属性和子属性,例如:
datastore.save({key: entity_key, data: entity_data, excludeFromIndexes: ['prop1', 'prop2.subprop1']});
在这里,我分享了一小段代码(来自您共享的代码段中的MCV),它可以工作并创建一个包含长属性的属性的实体:
const DataStore = require('@google-cloud/datastore');
const projectId = "YOUR_PROJECT_ID";
const datastore = DataStore({projectId});
const data = {name: {forename: 'David', surname: '<YOUR_LONG_STRING>'}, colour: 'purple'}
const Kind = "<YOUR_ENTITY_KIND>";
datastore
.save({key: datastore.key([Kind]), data: data, excludeFromIndexes: ['name.surname']})
.then(() => {
console.log(`Entity saved`);
})
.catch(err => {
console.error('ERROR:', err);
});
运行这段代码后,如果您检查Datastore dashboard中的实体,您将能够看到我的EmbeddedEntity定义为我在答案开始时分享的内容。