首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何找到具有匹配值的子对象的文档?

如何找到具有匹配值的子对象的文档?
EN

Stack Overflow用户
提问于 2022-08-02 19:01:37
回答 2查看 61关注 0票数 0

假设我有一个包含如下文档的集合

代码语言:javascript
复制
{
    "location" : "Tokyo",
    "region" : "Asia",
    "attraction": {
        "transportation" : "Subway",
        "food" : {
            "food_0" : {
                "name" : "Sushi",
                "price" : 100,
                "restaurant" : "Ookinza"
            },
            "food_1" : {
                "name" : "Sashimi",
                "price" : 200,
                "restaurant" : "Hibiki"
            },
            "food_2" : {
                "name" : "N/A",
                "price" : "N/A",
                "restaurant" : "N/A"
            }
        }
    }
},
{
    "location" : "Taipei",
    "region" : "Asia",
    "attraction": {
        "transportation" : "Subway",
        "food" : {
            "food_0" : {
                "name" : "Bubble tea",
                "price" : 50,
                "restaurant" : "The Alley"
            },
            "food_1" : {
                "name" : "Oyster cake",
                "price" : 100,
                "restaurant" : "Night market"
            },
            "food_2" : {
                "name" : "N/A",
                "price" : "N/A",
                "restaurant" : "N/A"
            }
        }
    }
},
{
    "location" : "Toronto",
    "region" : "North America",
    "attraction": {
        "transportation" : "Uber",
        "food" : {
            "food_0" : {
                "name" : "Raman",
                "price" : 300,
                "restaurant" : "Kinto"
            },
            "food_1" : {
                "name" : "Bubble tea",
                "price" : 200,
                "restaurant" : "Fresh Fruit"
            },
            "food_2" : {
                "name" : "N/A",
                "price" : "N/A",
                "restaurant" : "N/A"
            }
        }
    }
},

如何在“食物”的子对象中找到具有匹配字段的文档?也就是说,如果我想找到有餐厅的文件:“新鲜茶”?

我现在拥有的是:

代码语言:javascript
复制
app.get(route, (req, res) => {
    var detail = {};
    if(req.query.location){
        detail['location'] = req.query.location.toUpperCase();
    }
    if(req.query.region){
        detail['region'] = req.query.region.toUpperCase();
    }
    if(req.query.transportation){
        detail['attraction.transportation'] = new RegExp(req.query.transportation.split(","), "i"),
    }

    if(req.query.restaurant){
        detail['attraction.food.food_0'] = req.query.restaurant;
    }

    db.collection(config.dbCollections.foodDB)
        .aggregate([
            $match: detail,
        },
        {
            $lookup: {
       ... // code continues

现在,detail['attraction.food.food_0'] = req.query.restaurant只能找到具有匹配food_0.restaurant的文档,但我仍然找不到一种方法让它检查"food“中的所有子对象。

更新了更多信息:

用户可以选择输入多个搜索类别,我希望将所有搜索请求合并到“细节”中,并找到所有匹配的结果。也就是说,如果用户寻找transportation="Subway"food="Bubble tea",那么台北和多伦多都会因此而出现。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-02 19:31:24

使用动态值作为字段名通常被认为是反模式的,应该避免.不过,您可以将对象attraction.food转换为k-v元组数组,并使用您的条件执行搜索。对于您的情况,$anyElementTrue$map将帮助处理数组。

代码语言:javascript
复制
db.collection.aggregate([
  {
    "$addFields": {
      "test": {
        "$anyElementTrue": {
          "$map": {
            "input": {
              "$objectToArray": "$attraction.food"
            },
            "as": "t",
            "in": {
              $or: [
                {
                  $eq: [
                    "$$t.v.transportation",
                    "Subway"
                  ]
                },
                {
                  $eq: [
                    "$$t.v.name",
                    "Bubble tea"
                  ]
                }
              ]
            }
          }
        }
      }
    }
  },
  {
    $match: {
      test: true
    }
  },
  {
    "$unset": "test"
  }
])

这是供您参考的蒙戈游乐场

票数 1
EN

Stack Overflow用户

发布于 2022-08-02 19:45:07

一个可能的聚合管道

  1. 使用$addFields$objectToArray添加一个临时字段,该字段执行类似于javascript Object.entries()的操作
  2. 做匹配
  3. 使用$project 0删除添加的临时字段

游乐场

代码语言:javascript
复制
db.collection.aggregate([
  {
    "$addFields": {
      "foodArray": {
        "$objectToArray": "$attraction.food"
      },
      
    },
    
  },
  {
    "$match": {
      "foodArray.v.restaurant": "Fresh Fruit"
    }
  },
  {
    "$project": {
      "foodArray": 0
    },
    
  },
  
])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73212502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档