如何从数据库中筛选配方?

我有一个食谱集合,看起来像这样:


{

  "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

}

编辑:根据这个答案(thx @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

    }

感谢大家的帮助!


大话西游666
浏览 106回答 2
2回答

开心每一天1111

可以使用聚合管道实现此目的,$filter$match,以便您只考虑至少具有一种匹配成分的食谱$addFields使用$filter创建字段,以消除从中查询的成分数组OtherIngredientIngredients$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}}])

潇潇雨雨

对不起,我不知道Golang,但这是你需要的(是新的MongoDB 4.4):$functionlet filter = ["Eggs", "Milk", "Butter"];db.recipes.find({&nbsp; &nbsp; $expr: {&nbsp; &nbsp; &nbsp; &nbsp; $function: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; body: function(ingredients, filter) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (let i = 0; i < ingredients.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.indexOf(ingredients[i]) < 0) return false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args: ["$Ingredients", filter],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lang: "js"&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }});
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go