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

Arrays 如何从数据库中筛选配方?,arrays,database,mongodb,go,mongodb-query,Arrays,Database,Mongodb,Go,Mongodb Query,我有一个食谱集,看起来像这样: { "Name": "Omelet", "Ingredients": ["Eggs", "Milk", "Butter"] }, { "Name": "Pancakes", "Ingredients": ["Eggs", "Milk"

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

{
  "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
    }

谢谢大家的帮助

对不起,我不知道Golang,但这是您需要的(
$function
是新的MongoDB 4.4):

let filter=[“鸡蛋”、“牛奶”、“黄油”];
db.recipes.find({
$expr:{
$function:{
主体:功能(成分、过滤器){
for(设i=0;i
您可以通过使用

  • $匹配,这样你只考虑配方至少有一个匹配成分
  • $addFields创建
    其他配料
    字段,使用$filter从
    配料
  • $match仅选择配方,不含其他成分
  • $project以删除临时字段

这个解决方案会比使用$setIsubSet更好吗?可能不会,我总是忘记操作员退出。
[
  {$match: {Ingredients: {
        $in: ["Eggs","Milk","Butter"]
  }}},
  { $addFields: {
      OtherIngredient: {
        $filter: {
          input: "$Ingredients",
          cond: {$not: {$in: [
                "$$this",
                ["Eggs","Milk","Butter"]
          ]}}
        }
      }
  }},
  {$match: {"OtherIngredient": []}},
  {$project: {OtherIngredient: 0}}
])