Mongodb: select 文档中的所有字段,有条件地设置了少数字段的值
Mongodb: select all the fields in the document with few fields' value set conditionally
我们有一个名为 product
的集合,它存储具有不同定义属性的不同类型的产品(例如电子产品、食品、鞋类等)。用例是,我们希望 select 响应特定产品而返回的所有字段,而无需在 select
和 find
或 project
和 aggregate
中定义它们.这样做的原因是,产品的类型完全不同,我们不知道要select哪些字段。例如 - 电子产品的尺寸以英寸为单位,而食品的生产日期和有效期为单位。我们想要的只是,select 文档中的所有字段,在某些通用字段上有一些条件,如税金、gtin 等。
问题是,对于 find,我只能 select 或 deselect 字段而不添加任何条件,而对于聚合,我将不得不提及响应中需要的项目中的每个字段,我事先不知道字段名称。
这是适用于所有产品的通用产品架构:
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"
}]
即如果没有为产品定义税金或 gtin,则响应必须将税金设为 0,将 gtin 设为 null,并返回文档中存在的所有字段。
所以,我已经按照@Joe 的建议解决了我的三个用例。我在这里发布为获取所需结果而形成的查询(即,如果这些字段不存在于任何文档中以及文档中存在的不同字段,则将一些通用字段添加到具有默认值的产品文档中)。
1.获取所有文档
[{
$set: {
"gtin": {$ifNull: ["$gtin", null]},
"domain": { $ifNull: ["$domain", null] },
"tax": { $ifNull: ["$tax", 0] }
}
}];
2。通过匹配条件
获取特定文档
[{
"$match":{"_id":"60f668ccadb9e9147ed8a8ec"}
},
{
$set: {
"gtin": {$ifNull: ["$gtin", null]},
"domain": { $ifNull: ["$domain", null] },
"tax": { $ifNull: ["$tax", 0] }
}
}];
3。应用搜索并获取所需结果
[
{
$search: {
text: {
query: <STRING_TO_SEARCH>,
path: <PATH_TO_LOOK_IN>,
fuzzy: { maxEdits: 2}
}
}
},
{
$set: {
"gtin": {$ifNull: ["$gtin", null]},
"domain": { $ifNull: ["$domain", null] },
"tax": { $ifNull: ["$tax", 0] },
score: { $meta: "searchScore" }
}
}
];
我们有一个名为 product
的集合,它存储具有不同定义属性的不同类型的产品(例如电子产品、食品、鞋类等)。用例是,我们希望 select 响应特定产品而返回的所有字段,而无需在 select
和 find
或 project
和 aggregate
中定义它们.这样做的原因是,产品的类型完全不同,我们不知道要select哪些字段。例如 - 电子产品的尺寸以英寸为单位,而食品的生产日期和有效期为单位。我们想要的只是,select 文档中的所有字段,在某些通用字段上有一些条件,如税金、gtin 等。
问题是,对于 find,我只能 select 或 deselect 字段而不添加任何条件,而对于聚合,我将不得不提及响应中需要的项目中的每个字段,我事先不知道字段名称。
这是适用于所有产品的通用产品架构:
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"
}]
即如果没有为产品定义税金或 gtin,则响应必须将税金设为 0,将 gtin 设为 null,并返回文档中存在的所有字段。
所以,我已经按照@Joe 的建议解决了我的三个用例。我在这里发布为获取所需结果而形成的查询(即,如果这些字段不存在于任何文档中以及文档中存在的不同字段,则将一些通用字段添加到具有默认值的产品文档中)。
1.获取所有文档
[{
$set: {
"gtin": {$ifNull: ["$gtin", null]},
"domain": { $ifNull: ["$domain", null] },
"tax": { $ifNull: ["$tax", 0] }
}
}];
2。通过匹配条件
获取特定文档[{
"$match":{"_id":"60f668ccadb9e9147ed8a8ec"}
},
{
$set: {
"gtin": {$ifNull: ["$gtin", null]},
"domain": { $ifNull: ["$domain", null] },
"tax": { $ifNull: ["$tax", 0] }
}
}];
3。应用搜索并获取所需结果
[
{
$search: {
text: {
query: <STRING_TO_SEARCH>,
path: <PATH_TO_LOOK_IN>,
fuzzy: { maxEdits: 2}
}
}
},
{
$set: {
"gtin": {$ifNull: ["$gtin", null]},
"domain": { $ifNull: ["$domain", null] },
"tax": { $ifNull: ["$tax", 0] },
score: { $meta: "searchScore" }
}
}
];