如何查询和删除MongoDB中数组字段中的嵌入对象?

时间:2016-11-14 20:19:31

标签: mongodb mongodb-query

我正在尝试运行一个更新命令,在所有文档的数组字段中找到一个对象,然后从该数组字段中为所有文档提取它。我尝试了以下命令,它们不返回任何文档(nMatched:0)。

db.users.update({"likedQuizzes.quiz": { $elemMatch: quizObj}},{$pull: {"likedQuizzes.quiz": quizObj }});
db.users.update({"likedQuizzes": { $elemMatch: quizObj}},{$pull: {"likedQuizzes": quizObj }});

在上述案例中quizObj = {"title" : "2 Purple", "author" : "purple-tester1"}

以下是来自'用户'的示例文档。系列:

{

"_id" : ObjectId("581114330de9ac0c1445cdd6"),
"user" : "test-username1",  
"likedQuizzes" : [
        {
            "quiz" : {
                "title" : "2 Purple",
                "author" : "purple-tester1"
            },
            "date" : ISODate("2016-10-26T20:39:02.695Z")
        },
        {
            "quiz" : {
                "title" : "1 Purple",
                "author" : "purple-tester1"
            },
            "date" : ISODate("2016-10-26T20:39:12.374Z")
        },
        {
            "quiz" : {
                "title" : "4 Green",
                "author" : "green-tester1"
            },
            "date" : ISODate("2016-10-26T20:39:25.304Z")
        },
        {
            "quiz" : {
                "title" : "3 Green",
                "author" : "green-tester1"
            },
            "date" : ISODate("2016-10-26T20:39:37.326Z")
        },
        {
            "quiz" : {
                "title" : "2 Green",
                "author" : "green-tester1"
            },
            "date" : ISODate("2016-10-26T20:40:12.964Z")
        }
    ]
}

换句话说,我只是试图找出一个测验是否在用户中? " likedQuizzes"数组,如果是,则从该数组中删除它(以及" date"它被喜欢)。

经过一番研究后看起来似乎不太可能,但我还是想问,因为我认为我的架构可能与我研究中提出的例子不同。提前感谢任何指示。

3 个答案:

答案 0 :(得分:1)

您可以将文档重组为此结构:

{
    "_id" : ObjectId("581114330de9ac0c1445cdd6"),
    "user" : "test-username1",
    "likedQuizzes" : [
        {
            "title" : "2 Purple",
            "author" : "purple-tester1",
            "date" : ISODate("2016-10-26T20:39:02.695Z")
        },
        {
            "title" : "1 Purple",
            "author" : "purple-tester1",
            "date" : ISODate("2016-10-26T20:39:12.374Z")
        },
        {
            "title" : "4 Green",
            "author" : "green-tester1",
            "date" : ISODate("2016-10-26T20:39:25.304Z")
        },
        {
            "title" : "3 Green",
            "author" : "green-tester1",
            "date" : ISODate("2016-10-26T20:39:37.326Z")
        },
        {
            "title" : "2 Green",
            "author" : "green-tester1",
            "date" : ISODate("2016-10-26T20:40:12.964Z")
        }
    ]
}

之后...如果您运行以下命令:

db.users.update(
    {
        "likedQuizzes": { 
            $elemMatch: {
                "title" : "2 Purple", 
                "author" : "purple-tester1"
            }
        }
    },
    {
        $pull: { 
            "likedQuizzes": { 
                "title": "2 Purple",
                "author": "purple-tester1"
            }
        }
    }
);

你的$ pull现在可以使用了。 $ pull似乎不能很好地与$ elemMatch

一起玩

答案 1 :(得分:0)

那么,你要做的是将整个测验对象传递给$elemMatch并期望它从MongoDB返回匹配文档,但它不会那样工作。

您必须稍微修改一下您的查询

{"likedQuizzes.quiz.title": { $elemMatch: quizObj.title}

原因:mongodb不会为你进行字段比较。您应该有一个基于您可以查询的唯一标识符。

即使在RDBMS世界中,您也无法做到这一点。

您要做的是:

quizObj q;
q.title = "2 Purple";
q.author = "purple-tester1";

select * from quizTable where row = q.

答案 2 :(得分:0)

你可以尝试一下

db.users.update({"likedQuizzes": { $elemMatch: {"quiz.title" : "2 Purple", "quiz.author" : "purple-tester1"}}},
{$pull: {"likedQuizzes": {"quiz" : {"title" : "2 Purple", "author" : "purple-tester1"}}}})

您可以使用quizObj = {"quiz.title" : "2 Purple", "quiz.author" : "purple-tester1"}

希望它有所帮助。 然后在查询

下面
db.users.update({"likedQuizzes": { $elemMatch: quizObj }},{$pull: {"likedQuizzes": quizObj }})