如何使用Google Datastore查询带多条件的对象数组
搞定Google Datastore内嵌实体数组的多条件查询
嘿,我来帮你解决这个Google Datastore的查询问题!你遇到的多条件过滤对对象数组不生效的情况,确实是因为Datastore需要手动创建复合索引——这也是不少刚接触Datastore的开发者容易踩的坑,咱们一步步来解决:
一、先写对Node.js查询代码
首先,用@google-cloud/datastore库构造查询的时候,要注意:Datastore对内嵌实体数组的多条件过滤,会自动匹配数组中至少一个元素同时满足所有过滤条件的实体——这正好符合你的需求:找包含A@A.com,且该用户的UNTIL时间晚于当前时间的实体。
直接上代码示例:
const { Datastore } = require('@google-cloud/datastore'); const datastore = new Datastore(); async function getActiveEntitiesForUser(email) { // 生成和存储格式一致的当前时间字符串(如果存的是timestamp,直接用new Date()就行) const currentTime = new Date().toISOString(); // 替换成你的实体类型名称,比如你之前的ENTITY #1/#2对应的Kind const query = datastore .createQuery('YourEntityKind') // 过滤出包含指定邮箱的协作项 .filter('COLLABORATORS.EMAIL', '=', email) // 过滤出该协作项的权限未过期(当前时间 < UNTIL) .filter('COLLABORATORS.UNTIL', '>', currentTime); const [entities] = await query.run(); // 去掉实体的Key信息,只返回属性内容(按需选择) return entities.map(entity => datastore.omitKey(entity)); } // 调用测试 getActiveEntitiesForUser('A@A.com') .then(results => console.log('符合条件的实体:', results)) .catch(err => console.error('查询出错:', err));
二、必须创建的复合索引
为什么之前多条件过滤不生效?因为Datastore只自动创建单属性的索引,当你同时过滤两个不同属性(COLLABORATORS.EMAIL和COLLABORATORS.UNTIL)时,必须手动定义复合索引。
具体操作步骤:
- 在项目根目录新建
index.yaml文件,填入以下内容(记得替换成你的实体Kind名称):
indexes: - kind: YourEntityKind properties: - name: COLLABORATORS.EMAIL - name: COLLABORATORS.UNTIL direction: desc # 因为我们用的是">"比较,desc方向的索引更高效,用asc也能正常工作
- 用gcloud命令部署这个索引:
gcloud datastore indexes create index.yaml
部署后需要等几分钟让索引生效,之后你的查询就能正常返回结果了。
三、几个要注意的细节
- 时间格式要统一:从你提供的控制台存储格式看,
UNTIL是字符串类型的ISO时间,所以查询时也要用toISOString()生成一致的格式;如果存储的是Datastore的timestampValue类型,直接用new Date()作为比较值即可,Datastore会自动处理。 - 内嵌实体的路径正确:你的
COLLABORATORS是内嵌实体数组,所以用COLLABORATORS.EMAIL和COLLABORATORS.UNTIL作为属性路径是完全正确的,Datastore会遍历数组里的每个内嵌实体进行匹配。 - 索引生效时间:新索引部署后大概需要5-10分钟才能完全生效,如果刚部署完查询没结果,别急,等一会儿再试。
按照这个流程来,就能顺利拿到你想要的实体啦!
内容的提问来源于stack exchange,提问作者charnould
相关产品推荐
相关产品推荐

