一尘不染

Google数据存储区合并(联合)多组实体结果以达到OR条件

node.js

我正在使用带有数据存储数据库的Google App Engine上的NodeJS。

由于数据存储区不支持OR运算符,因此我需要运行多个查询并合并结果。

我计划运行多个查询,然后将结果组合到单个实体对象数组中。我已经有一个查询正在工作。

问题:将数据存储区返回的两套(或多套)实体(包括重复数据删除)组合在一起的合理有效方式是什么?我相信这将是集合论的“联合”行动。

这是基本查询大纲,将使用一些不同的过滤器多次运行以实现所需的OR条件。

  //Set requester username
  const requester = req.user.userName;
  //Create datastore query on Transfer Request kind table
  const task_history = datastore.createQuery('Task');
  //Set query conditions
  task_history.filter('requester', requester);
  //Run datastore query
  datastore.runQuery(task_history, function(err, entities) {
    if(err) {
      console.log('Task History JSON unable to return data results. Error message: ', err);
      return;
      //If query works and returns any entities
    } else if (entities[0]) {
      //Else if query works but does not return any entities return empty JSON response
      res.json(entities); //HOW TO COMBINE (UNION) MULTIPLE SETS OF ENTITIES EFFICIENTLY?
      return;
    }
  });

阅读 201

收藏
2020-07-07

共1个答案

一尘不染

恕我直言,最有效的方法是在第一阶段使用仅键查询,然后将获得的键组合到一个列表中(包括重复数据删除),然后仅通过键查找即可获得实体。从投影查询

仅键查询

仅键查询(这是投影查询的一种)仅返回结果实体的键,而不是实体本身,因此其延迟和成本比检索整个实体要低。

通常,先执行仅键查询,然后从结果中获取实体的子集,而不是执行可能会获取比实际需要更多的实体的一般查询,这样比较经济。

以下是创建仅键查询的方法:

const query = datastore.createQuery()
  .select('__key__')
  .limit(1);

此方法解决了当您尝试直接合并通过常规非键查询获得的实体列表时可能遇到的几个问题:

  • 您无法正确进行重复数据删除,因为您无法区分具有相同值的不同实体与出现在乘法查询结果中的相同实体之间的差异
  • 通过属性值比较实体可能会比较棘手,并且绝对比仅比较实体键要慢/更多的计算开销
  • 如果您无法在一个请求中处理所有结果,那么您将花费不必要的数据存储成本来读取它们,而无需实际使用它们
  • 仅处理实体键时,将实体的处理拆分为多个请求(例如,通过任务队列)要简单得多

也有一些缺点:

  • 这可能会有点慢,因为您要两次访问数据存储区:一次是输入密钥,一次是获取实际实体
  • 您不能利用仅通过非键的投影查询来获取所需属性的优势
2020-07-07