javascript - 如果提供了空数组,则忽略 $in
问题描述
我有以下模型:
export type IMangaModel = Document & {
_id: string;
title: string;
description: string;
demographic: Array<string>;
genre: Array<string>;
tags: Array<string>;
related: Array<IMangaModel>;
cover_image: {
extraLarge: string | null;
large: string | null;
medium: string | null;
};
banner: string | null;
al_id: number;
al_url: string;
likes: Array<IUserModel['_id']>;
};
注意:接口与模型完全匹配,但我将其粘贴为它更短。
我正在使用以下数据过滤此集合:
includeFilters: {
genres: Array<string>;
tags: Array<string>;
demographics: Array<string>;
};
excludeFilters: {
genres: Array<string>;
tags: Array<string>;
demographics: Array<string>;
};
我想要实现的是找到每个文档并检查相应的数组是否具有我通过 includeFilters 发送的数组中的至少一个值。虽然它没有通过 excludeFilters 发送的值。
为此,我使用了以下查询:
const results = await this._manga
.find(
{
tags: {
$elemMatch: {
$in: data.includeFilters.tags,
$nin: data.excludeFilters.tags,
},
},
genre: {
$elemMatch: {
$in: data.includeFilters.genres,
$nin: data.excludeFilters.genres,
},
},
demographic: {
$elemMatch: {
$in: data.includeFilters.demographics,
$nin: data.excludeFilters.demographics,
},
},
},
{ al_id: 1 }
);
只要includeFilters 数组中的所有数组都至少有一个值,这似乎就可以正常工作。但是,如果提供了一个空数组,那么在 $in 中找不到匹配项,据我所知,$in 需要至少存在一个值,但由于没有提供任何内容,因此什么也找不到。另一方面,$nin工作正常(至少我想这样认为),因为它没有试图排除任何值。
我想要实现的是,如果向 $in 提供了一个空数组,那么它会直接跳过该过滤器并且不查看它。在 mysql 中执行此操作时,如果提供了一个空数组,则将其忽略并返回每条记录作为结果。这就是我想要的 mongodb。
到目前为止,我尝试过的是几件事。
首先,我尝试将所有可能的值添加到空数组中,这不起作用,原因之一是,并非所有文档都有标签、流派和人口统计数据。所以最终将近 90% 的文档没有包含在结果中。
我尝试的第二件事是在连接选项中启用ignoreUndefined选项。然后在创建查询时检查长度是否为 0,如果是,则将 undefined 传递给$in。这没有用。
我尝试的第三件事是遍历所有可能的情况,其中某个数组为空,由于显而易见的原因,这很糟糕,所以我抓了它。
我尝试的第四件事是创建一个函数来构建各种动态查询,由于可能性的数量,这也变得非常混乱。
我尝试的第五件事也是最后一件事是使用$or并认为会以某种方式跳过空结果。
解决方案
为了更好地使用 TypeScript,您可以使用 Nenad 的方法和 ES6 方法
const filters = Object.fromEntries(
Object.entries(body).flatMap(([filterType, filters]) =>
Object.entries(filters)
.filter(([, values]) => values.length)
.map(([key, value]) =>
filterType === "includeFilters"
? [key, { $elemMatch: { $in: [...value] } }]
: [key, { $elemMatch: { $nin: [...value] } }]
)
)
);
推荐阅读
- delphi - 终止“睡眠”线程
- php - Laravel eloquent 使用关系列更新列
- python - 将特定行旋转到列中
- python - 使用带有 SQS 代理的 prometheous 客户端监视在 celery worker 上运行的任务
- ruby - 破折号/连字符在 Ruby 中重置 FTP#list 中的路径
- python - 来自浏览器、Flask 和 jQuery 的错误请求
- laravel - Laravel Paypal 定期付款 - 错误的 NextBillingDate - 成功付款后
- azure-devops - Azure devops Web 扩展 - 跨所有组织的访问令牌
- jenkins - 在 Jenkins 中使用 Cli 或 REST API 在 Jenking 中创建用户、作业和管道
- android - 由于图标按钮而出现此渲染 flex 错误