arrays - 如何从数据库中过滤食谱?
问题描述
我有一个食谱集合,看起来像这样:
{
"Name": "Omelet",
"Ingredients": ["Eggs", "Milk", "Butter"]
},
{
"Name": "Pancakes",
"Ingredients": ["Eggs", "Milk", "Butter", "Flour", "Sugar", "Salt"]
},
{
"Name": "Random recipe",
"Ingredients": ["Eggs", "Milk"]
}
我正在尝试获取包含完全包含在查询中的成分的食谱。例如,如果我有查询鸡蛋、牛奶和黄油,那么我必须从上面的集合中获取煎蛋卷和“随机食谱”,而不是煎饼,因为我没有另外 3 种必要的成分。如果我只有鸡蛋和牛奶,那么它必须只返回“随机食谱”。换句话说,我只想要可以用现有原料制作的食谱。我搜索了文档,但找不到确切的实现方式。有任何想法吗?我正在使用 Golang 作为我的后端,所以如果你在上面写一个例子会更好。如果有任何帮助,我将不胜感激。
现在我写了这个函数,它返回所有带有某些成分的食谱,但这没有考虑到缺少的成分和不需要所有转移成分的食谱:
func GetTestRecipesFromDB(ingredients []string) *[]Recipe {
collection := client.Database("food_db").Collection("recipes")
ctx, _ := context.WithTimeout(context.Background(), 10 * time.Second)
var recipes []Recipe
var cursor *mongo.Cursor
cursor, err := collection.Find(ctx, bson.D{
{"Ingredients", bson.D{{"$all", ingredients}}},
})
if err != nil {
log.Fatal(err)
return nil
}
if err = cursor.All(ctx, &recipes); err != nil {
log.Fatal(err)
return nil
}
return &recipes
}
编辑:根据这个答案(谢谢@MontgomeryWatts 的建议)我在Go中写了这个并且它有效:
query := bson.M{
"$match" : bson.M{
"$expr" : bson.M{
"$setIsSubset": []interface{}{
"$Ingredients",
ingredients,
},
},
},
}
cursor, err := collection.Aggregate(ctx, []bson.M{query})
if err != nil {
log.Fatal(err)
return nil
}
感谢大家的帮助!
解决方案
您可以通过使用$filter的聚合管道来完成此操作
- $match 以便您只考虑具有至少一种匹配成分的食谱
- $addFields 使用 $filter 创建
OtherIngredient
字段以消除查询的成分数组Ingredients
- $match 只选择没有其他成分的食谱
- $project 删除临时字段
[
{$match: {Ingredients: {
$in: ["Eggs","Milk","Butter"]
}}},
{ $addFields: {
OtherIngredient: {
$filter: {
input: "$Ingredients",
cond: {$not: {$in: [
"$$this",
["Eggs","Milk","Butter"]
]}}
}
}
}},
{$match: {"OtherIngredient": []}},
{$project: {OtherIngredient: 0}}
])
推荐阅读
- android - 在Android中出现异常后我应该如何重新启动/重试Kotlin协程
- python - python 3中导入函数的范围是什么
- python - Pyemma 转换矩阵返回意外大小的数组
- spring-boot - 我们如何避免在 Spring Boot 可执行 JAR 中分叉 java 进程?
- extjs - Extjs 中的多个窗口
- jointjs - 如何对 JointJS 中的链接删除事件做出反应
- flutter - 如何用来自material.io的flutter实现这个材质卡?
- python - 等待多个图表加载
- ansible - 如何在模板字符串时使用消息“模板错误:没有名为 'oo_prepend_strings_in_list' 的过滤器”来修复 Ansible 错误
- html - 语义网是否使用 XML 而不是 HTML 或 JSON?