代码之家  ›  专栏  ›  技术社区  ›  Strider

计算嵌套字段的出现次数

  •  0
  • Strider  · 技术社区  · 6 年前

    我正在尝试计算嵌套字段中具有匹配条件的文档数。

    我的模式定义如下:

    let userSchema = new Schema({
      //...
      interests: [{
        type: Schema.Types.ObjectId,
        ref: 'Interests'
      }],
      //...
    });
    
    let interestSchema = new Schema({
      id: ObjectId,
      name: {
        type: String,
        required: true
      },
      //...
    });
    

    计数必须反映用户选择相同名称兴趣的次数。

    例如,我必须得到2的结果,并在以下文档中对“编码”感兴趣:

    {
      //Other Fields of user 1
      "interests": [
         {
           "id": "XXX"
           "name": "coding"
         }, 
         {
           "id": "YYY"
           "name": "surfing"
         }]
    }
    
    {
      //Other Fields of user 2
      "interests": [
         {
           "id": "ZZZ"
           "name": "coding"
         }
       ]
    }
    

    我查了一下 countDocuments 方法,但它似乎不允许这种计数。


    编辑+第一个解决方案:

    我就是这样解决的:

    const res = await UserModel.aggregate([
      {
        $unwind: '$interests'
      },
      {
        $lookup: {
          from: "interests",
          localField: "interests",
          foreignField: "_id",
          as: "interests"
        }
      },
      {
        $match:{
          "interests.name": name
        }
      },
      {
        $count: "count"
      }
    ]);
    return res[0].count;
    

    事实上,兴趣是一个引用类型,除非传递 lookup 阶段。我不确定这是否是一个好的性能解决方案,因为 unwind 阶段必须通过数据库的所有用户,并为每个用户的兴趣创建一个新元素。这就是为什么我不把它作为答案发布的原因

    1 回复  |  直到 6 年前
        1
  •  0
  •   Strider    6 年前

    与…合作 elemMatch ,为了嵌入 Interest User 而不是引用它:

    let userSchema = new Schema({
      //...
      interests:  [InterestSchema],
      //...
    });
    
    let InterestSchema = new Schema({
      id: ObjectId,
      name: {
        type: String,
        required: true
      },
      //...
    });
    

    这就是我如何使用 埃勒迈奇 :

    const count = UserModel
      .where('interests').elemMatch( interest => {
        interest.where({ name: name });
      })
      .count();
    

    正如我在问题中提到的,总的来说 method 有效,但我不确定它的性能,因为我使用的是引用数组而不是子文档,这就是为什么我必须更改集合的架构的原因。