首页 > 解决方案 > 如何计算包含数组中值的文档?

问题描述

我有一个 MongooseabTest文档,它有两个字段:

  1. status. 这是一个字符串枚举,可以是active,inactivedraft.
  2. validCountryCodes. 这是一个字符串枚举数组(GBEUAU)。默认情况下,它将为空。

在数据库中,在任何时候,我只希望abTest每个都有一个活动,validCountryCode所以我在创建或编辑新的abTest.

为此,我编写了一个函数,该函数尝试计算具有statusofactive且包含countryCodes.

如果计数大于一,该函数将返回。如果是这样,我会抛出一个验证错误。

if (params.status === 'active') {
  const activeTestForCountryExists = await checkIfActiveAbTestForCountry(
    validCountryCodes,
  );
  if (params.activeTestForCountryExists) {
    throw new ValidationError({
      message: 'There can only be one active test for each country code.',
    });
  }
}

const abTest = await AbTest.create(params);

checkIfActiveAbTestForCountry()看起来像这样:

const checkIfActiveAbTestForCountry = async countryCodes => {
  const query = {
    status: 'active',
  };

  if (
    !countryCodes ||
    (Array.isArray(countryCodes) && countryCodes.length === 0)
  ) {
    query.validCountryCodes = {
      $eq: [],
    };
  } else {
    query.validCountryCodes = { $in: [countryCodes] };
  }

  const count = await AbTest.countDocuments(query);
  return count > 0;
};

计数查询不仅应该计算完全匹配的数组,还应该计算任何部分匹配。

如果在数据库中有一个active abTestwithvalidCountryCodes数组['GB', 'AU',],则尝试创建一个新abTest的 with['GB'应该失败。因为已经有一个带有GBas 的测试validCountryCode

同样,如果有一个带有validCountryCodes数组的测试['AU'],那么创建一个带有validCountryCodesof的测试['AU,'NZ']也应该失败。

现在都没有强制执行。

我怎样才能做到这一点?这是否可能编写一个查询来检查这个?

我考虑过迭代params.validCountryCodes并计算包含每个文档的文档,但这似乎是不好的做法。

标签: node.jsmongodbmongoosemongodb-query

解决方案


您正在使用正确的 mongo-query 来满足您的要求。您能否验证从您的应用程序执行的实际查询是否相同?在这里检查

{ status: 'active', validCountryCodes: { $in: [ countryCodes ] } }

例如;以下查询:

{ status: 'active', validCountryCodes: { $in: ['GB' ] } }

应该匹配文件:

{ status: 'active', validCountryCodes: ['AU','GB'] }

推荐阅读