【发布时间】:2021-09-27 03:06:18
【问题描述】:
我们有一个名为product 的集合,它存储具有不同定义属性的不同类型的产品(例如电子产品、食品、鞋类等)。用例是,我们希望选择响应特定产品返回的所有字段,而不在select 和find 或project 和aggregate 中定义它们。这样做的原因是,产品的类型完全不同,我们不知道要选择哪些字段。例如 - 电子产品的尺寸以英寸为单位,而食品则具有制造日期和有效期。我们想要的是,选择文档中存在的所有字段,并在某些通用字段上具有某些条件,例如 - tax、gtin 等。
问题是,使用 find 我只能选择或取消选择字段而不添加任何条件,而使用聚合我将不得不提及响应中需要的项目中的每个字段,并且我事先不知道字段名称。
这是适用于每个产品的通用产品架构:
const mongoose = require('mongoose');
const schema = mongoose.Schema({
name: { type: String, required: [true, 'Product name is required.'] },
product_type: String,
description: String,
company: String,
gtin: String,
tax: Number,
price: Number
}, {strict: false});
对于这两个产品文档:
[{
"name": "Coca-Cola Soft Drink, 2L PET Bottle",
"product_type": "Beverages",
"description": "The original cola flavoured refreshment to be enjoyed with loved ones",
"company": "Coca-Cola",
"gtin": "74125896352SDSFEED343",
"price": 83,
"package_weight": "2.14 Kg"
},
{
"name": "Lenovo X1 Titanium Yoga (Intel)",
"product_type": "Electronics",
"description": "Lenovo X1 Titanium Yoga (Intel)",
"company": "Lenovo",
"price": 50000,
"tax": 5,
"screen_size": "14 inches",
"operating_system": "Windows 10 Pro"
}]
预期输出是:
[{
"name": "Coca-Cola Soft Drink, 2L PET Bottle",
"product_type": "Beverages",
"description": "The original cola flavoured refreshment to be enjoyed with loved ones",
"company": "Coca-Cola",
"gtin": "74125896352SDSFEED343",
"price": 83,
"tax": 0,
"package_weight": "2.14 Kg"
},
{
"name": "Lenovo X1 Titanium Yoga (Intel)",
"product_type": "Electronics",
"description": "Lenovo X1 Titanium Yoga (Intel)",
"company": "Lenovo",
"gtin": null,
"price": 50000,
"tax": 5,
"screen_size": "14 inches",
"operating_system": "Windows 10 Pro"
}]
即如果没有为产品定义 tax 或 gtin,则响应必须返回 tax 为 0 且 gtin 为 null 以及文档中存在的所有字段。
【问题讨论】:
-
您是否尝试过使用
$set或$addFields进行聚合? -
@Joe 不,我没有。我现在试一试。谢谢你的建议。
-
@Joe 当我将它用于获取特定产品或所有产品时,这解决了我的问题。但是,对于搜索聚合,它不是。我在响应中也需要 searchScore。当不存在但不存在 searchScore 时,它返回 gtin null 和 tax 0 的结果,因为在这种情况下我已经删除了项目。
-
这是我的聚合搜索查询:
{ $search: { text: { query: search_string, path: search_path, fuzzy: { maxEdits: 2} } } }, { $set: { "gtin": {$ifNull: ["$gtin", null]}, "domain": { $ifNull: ["$domain", null] }, "tax": { $ifNull: ["$tax", 0] } } } ];如果我在这里使用 project 来获取 searchScore,我将不得不提及字段名称,如果我不使用 project 将不会得到 searchScore结果。 -
你确定不能在 $set 中获取 searchScore 吗?
标签: mongodb mongoose aggregate