Mongo查询操作,用于匹配同一索引中的两个元素

时间:2019-06-19 17:02:50

标签: mongodb mongodb-query

项目范围:我正在制作新闻源,例如Facebook。而且我有一个喜欢按钮功能,单击该按钮后,它会在帖子中添加喜欢的对象。

问题可以说我有两个帖子,帖子A和帖子B。

如果我喜欢帖子A,然后再次喜欢,则我的服务器返回“用户已经喜欢帖子”,可以。

但是,如果我喜欢帖子B,则服务器会返回相同的“用户已经喜欢帖子”

查询:

Feed.findOne({
      owner: req.body.authorId,
      $and: [
        {
          "posts.likes.likeList": {
            $elemMatch: { user: req.user._id }
          }
        },
        { posts: { $elemMatch: { _id: req.body.postId } } }
      ]
    }).then(checkedFeed => {
      if (checkedFeed) {
        return res.status(400).json({ Error: "User has already liked post" });
      }

我认为问题所在,当用户喜欢帖子B而喜欢帖子A时,$and运算符将req.user._idposts.likes.likeList匹配在$and数组的第一个索引中发布A。然后,它与_id数组的第二个索引中的posts的{​​{1}}相匹配。然后返回整个供稿作为匹配项。

因此,如果我在这方面是正确的,我该如何编写一个与$and用户列表相匹配的帖子ID($and数组的第二个索引)的查询?

架构

post.likes.likeList

测试数据*

{
  owner: {
    type: Schema.Types.ObjectId,
    ref: "userType"
  },
  posts: [
    {
      likes: {
        totalLikes: { type: Number, default: 0 },
        likeList: [
          {
            user: { type: Schema.Types.ObjectId, ref: "User" },
            avatar: { type: String },
            name: { type: String },
            date: {
              type: Date,
              default: Date.now
            }
          }
        ]
      }
});

每个建议答案的新查询

    {

//POST B <-------
        "_id" : ObjectId("5d0a61bc5b835b2428289c1b"),
        "owner" : ObjectId("5c9bf6eb1da18b038ca660b8"),
        "posts" : [ 
            {
                "likes" : {
                    "totalLikes" : 0,
                    "likeList" : []
                },
                "_id" : ObjectId("5d0a61bc5b835b2428289c1c"),
                "postBody" : "Test text only",
                "author" : {
                    "userType" : "User",
                    "user" : ObjectId("5c9bf6eb1da18b038ca660b8"),
                    "name" : "Amari DeFrance",
                    "avatar" : "https://stemuli.blob.core.windows.net/stemuli/profile-picture-e1367a7a-41c2-4ab4-9cb5-621d2008260f.jpg"
                }
            }, 
            {
//Post A <------
                "likes" : {
                    "totalLikes" : 1,
                    "likeList" : [ 
                        {
                            "_id" : ObjectId("5d0a66efbac13b4ff8b3b1c8"),
                            "user" : ObjectId("5c9bf6eb1da18b038ca660b8"),
                            "avatar" : "https://stemuli.blob.core.windows.net/stemuli/profile-picture-e1367a7a-41c2-4ab4-9cb5-621d2008260f.jpg",
                            "name" : "Amari DeFrance",
                            "date" : ISODate("2019-06-19T16:46:39.177Z")
                        }
                    ]
                },
                "postBody" : "Test photo",
                "author" : {
                    "userType" : "User",
                    "user" : ObjectId("5c9bf6eb1da18b038ca660b8"),
                    "name" : "Amari DeFrance",
                    "avatar" : "https://stemuli.blob.core.windows.net/stemuli/profile-picture-e1367a7a-41c2-4ab4-9cb5-621d2008260f.jpg"
                },
                "date" : ISODate("2019-06-19T16:25:26.123Z")
            }
        ],
        "__v" : 3
    }

MongoDB query test with post B having liked post from the user

1 个答案:

答案 0 :(得分:1)

您可以使用documentationlikeList转换为布尔值数组。然后,您可以使用$map检查某个用户是否属于特定用户。然后,您需要对posts(外部数组)执行相同的技巧,将两个条件与$and结合使用将为您带来所需的结果,请尝试:

Feed.aggregate([
    {
        $match: {
            $expr: {
                $and: [
                    { $eq: [ "$owner", req.body.authorId ] },
                    {
                        $anyElementTrue: {
                            $map: {
                                input: "$posts",
                                in: {
                                    $and: [
                                        { $eq: [ "$$this._id", req.body.postId ] },
                                        {
                                            $anyElementTrue: {
                                                $map: {
                                                    input: "$$this.likes.likeList",
                                                    as: "like",
                                                    in: { $eq: [ "$$like.user", req.user._id ] }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                ]
            }
        }
    }
])

$anyElementTrue