【问题标题】:Mongoose aggregate multiple collections with match and filteringMongoose 使用匹配和过滤聚合多个集合
【发布时间】:2017-05-04 22:39:00
【问题描述】:

我有三个猫鼬模型

当用户喜欢某样东西时,它会保存在 Liked 集合中。但我想做的是。查询 10 个用户以前不喜欢且不是他自己的产品的可用产品。我不知道如何在一个查询中实现这一点。有可能吗?

用户:

{
    password: String,
    type: {
        type: String,
        enum: ['user', 'admin'],
        required: true,
        default: "user"
    },
    firstName: {type: String},
    middleName: {type: String},
    lastName: {type: String},
    gender: {type: String},
    profilePicture: {type: Object},
    setOwnProfilePicture: {type: Boolean, default: false},
    facebook:{
        id: {type: String},
        token: {type: String}
    }
}

产品:

{
    condition: {
        type: String,
        enum: ['Als nieuw', 'Goed', 'Redelijk', 'Matig'],
        required: true,
        default: "Goed"
    },
    type: {
        type: String,
        enum: ['Ruilen', 'Doneren'],
        required: true,
        default: "Ruilen"
    },
    zipCode: {type: String},
    houseNumber: {type: String},
    distance: {type: Number},
    likes: {type: Number, default: 0},
    dislikes: {type: Number, default: 0},
    title: {type: String},
    description: {type: String},
    owner: {type: Schema.ObjectId},
    images: { type : Array , "default" : [] }
}

喜欢:

{
    ownerProductID: {type: Schema.ObjectId},
    productID: {type: Schema.ObjectId},
    liked: Boolean
}

更新: 我找出要使用的查询,但在结果中我有一个名为 liked 的字段,但我想过滤掉它,所以我的结果中没有任何额外的值。

我现在使用的查询:

db.products.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $match: {'owner': {$ne: ObjectId("583f2f33ee975f4e8560b9fe")}}
        },

        // Stage 2
        {
            $lookup: {
                "from" : "likes",
                "localField" : "_id",
                "foreignField" : "productID",
                "as" : "liked"
            }
        },

        // Stage 3
        {
            $match: {'liked.ownerProduct': {$nin: [ObjectId("585834609bb1aa1cbe98257b")]}}
        },

        // Stage 4
        {
            $limit: 10
        },

    ]

);

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    我设法得到了我想要的结果。通过使用此查询:

    db.products.aggregate(
    
        [
            {
                $match: {'owner': {$ne: ObjectId("583f2f33ee975f4e8560b9fe")}}
            },
            {
                $lookup: {
                    "from" : "likes",
                    "localField" : "_id",
                    "foreignField" : "productID",
                    "as" : "liked"
                }
            },
            {
                $match: {'liked.ownerProduct': {$nin: [ObjectId("585834609bb1aa1cbe98257b")]}}
            },
            {
                $limit: 10
            },
            {
                $project: {
                    _id: 1,
                    owner: 1,
                    zipCode: 1,
                    title: 1,
                    description: 1,
                    houseNumber: 1,
                    images: 1,
                    dislikes: 1,
                    likes: 1,
                    type: 1,
                    condition: 1
                }
            },
        ]
    );
    

    【讨论】:

      【解决方案2】:

      使用聚合在多个级别上进行过滤。

      假设您有USER_OBJECTID,首先过滤所有者的产品,然后使用Liked 加入集合并使用用户ID 再次过滤。

      db.Product.aggregate([
          {$match: {'owner': {$ne: '<USER_OBJECTID>'}}},
          {$lookup: {
              from: 'liked',
              localField: '_id',
              foreignField: 'productID',
              as: 'likes'
              }
          },
          {$match: {'likes.userID': {$nin: [<USER_OBJECTID>]}}},
          {$limit: 10}
      ])
      

      【讨论】:

      • 谢谢你帮助我,但是我稍微改变了我的模型。 likes 集合现在只包含产品 ID,因为在产品模型中我指的是用户。我需要改变什么?
      • @toonvanstrijp 你如何存储哪个用户喜欢哪个产品?喜欢的ownerProductId 是什么?
      • 实际上该产品喜欢其他产品。所以我需要跟踪哪些产品彼此喜欢或不喜欢。这是一种用户可以交易产品的火种系统。但我正在为 mongoDB 查询而苦苦挣扎。在 Liked 集合中,我会跟踪哪些产品喜欢什么。我需要给用户一个他喜欢的产品列表。所以我需要从某个产品中筛选出哪些产品可以被喜欢。希望这能让我的商店更清晰?
      • ownerProductId 是喜欢其他产品的产品
      猜你喜欢
      • 2023-03-23
      • 2016-10-14
      • 2016-07-11
      • 2018-09-17
      相关资源
      最近更新 更多