MongoDB:具有数组输入的复杂查询

Posted

技术标签:

【中文标题】MongoDB:具有数组输入的复杂查询【英文标题】:MongoDB: A complex query with array input 【发布时间】:2019-04-15 04:47:38 【问题描述】:

我一直在为以下查询寻找解决方案。

1) 用户可以选择许多类别和子类别。

2) 用户可以看到所有其他用户如何在一定范围内选择相同的类别和子类别。

这里是用户的Schema

const userSchema = new Schema(
  
    image:  type: String, default: 'NA' ,
    firstName:  type: String, default: 'first name' ,
    lastName:  type: String, default: 'last name' ,
    email:  type: String, lowercase: true, unique: true, trim: true ,
    password:  type: String, min: 6 ,
    gender:  type: String, emun: ['male','female','other'] ,
    about:  type: String, default: 'about you' ,
    address: 
      zipCode:  type: Number, default: 000000 ,
      place:  type: String, default: 'place' ,
      street:  type: String, default: 'street' ,
      country:  type: String, default: 'Country' ,
      location: 
        type:  type: String, default:'Point',
        coordinates:  type:[Number], index:'2dsphere', default:[0,0] 
      
    ,
    interests: [
      
        _id : false,
        category: 
          id:  type: Schema.Types.ObjectId, ref: 'Category' ,
          name:  type: String 
        ,
        subCategory: [
          
            _id : false,
            id:  type: Schema.Types.ObjectId, ref: 'Subcategory' ,
            name:  type: String 
          
        ]
      
    ]
  
);

在我的控制器中,这是我尝试过的

homeData: async (req, res, next) => 
    const limit = Number(req.params.limit);
    const  latitude, longitude, minDistance, maxDistance  = getUserCurrentLocation(req);

    const usersWithSameInterests = await User.aggregate([
     
       "$geoNear": 
          "near": 
            "type": "Point",
            "coordinates": [longitude, latitude]
          ,
          "distanceField": "distance",
          "minDistance": minDistance,
          "maxDistance": maxDistance,
          "spherical": true,
          "query":  "location.type": "Point" 
        
      ,
      
        "$match":  "interests":  "$elemMatch": name: 'Sports'  // hard coded for testing
      ,
       "$sort":  "distance": 1  ,
       "$limit" : limit ,
      
        "$project": 
          "_id": 1,
          "image": 1,
          "firstName":1,
          "lastName":1,
          "distance": 1,
          "createdAt": 1
        
      
    ]);

    return respondSuccess(res, null, 
      newNotification: false,
      usersWithSameInterests: usersWithSameInterests
    );
  ,

我得到的回应是


  "success": true,
  "message": "query was successfull",
  "data": 
      "newNotification": false,
      "usersWithSameInterests": []
  

示例类别和子类别 类别:运动 子类别:板球、足球、曲棍球、网球

类别:学习语言 子类别:英语、德语、西班牙语、印地语

期待急需的帮助。

谢谢。

【问题讨论】:

【参考方案1】:

您似乎有一些不匹配的列。

$geonear 管道上,"query": "location.type": "Point" 行应该是:'query': 'address.location.type': 'Point'

$match 管道上, "interests": "$elemMatch": name: 'Sports' 应该是'interests': '$elemMatch:' 'category.name': 'Sports'

编辑

要匹配类别和子类别字段上的多个兴趣,您可以在$match 管道上使用$in 运算符。像这样:


  'interests.category.name':  $in: ['Sports'] ,
  'interests.subCategory.name': $in: ['Soccer']

它将返回类别名称中包含 Sports 且子类别名称中包含 Soccer 的任何人。

【讨论】:

非常感谢您的回复,我做了一些调试并找出了不匹配的列,真正的问题是一个用户有多个兴趣。例如:如果登录用户有 1+ 个兴趣 Sports, Traveling, Music 那么 $elemMatch 应该寻找一个数组。我们如何做到这一点?我们如何查询类别和子类别?请更新您的答案。再次感谢。 我猜 $in 运算符会对此有所帮助。您可以在the documentation 上查看更多信息

以上是关于MongoDB:具有数组输入的复杂查询的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot MongoDb 复杂查询

mongodb高级聚合查询

mongodb高级聚合查询

MongoDB分组查询,聚合查询,以及复杂查询

第十二章 springboot + mongodb(复杂查询)

Mongodb查询聚合和Groupby复杂过滤、求和、百分比查询