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

时间:2018-11-12 12:52:54

标签: node.js mongodb api express mongoose

我坚持为以下查询找到解决方案。

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 个答案:

答案 0 :(得分:1)

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

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

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

修改

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

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

它将返回在类别名称中具有“运动”并且在子类别名称中具有“足球”的任何人。