【问题标题】:MongoDB: A complex query with array inputMongoDB:具有数组输入的复杂查询
【发布时间】: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": []
  }
}

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

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

期待急需的帮助。

谢谢。

【问题讨论】:

    标签: node.js mongodb api express mongoose


    【解决方案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 上查看更多信息
    猜你喜欢
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2021-02-23
    • 2013-02-26
    相关资源
    最近更新 更多