Nodejs mongo:关于“使用$slice时将返回文档中所有的键”

Nodejs mongo:关于“使用$slice时将返回文档中所有的键”

除非特别声明,否则使用"$slice"时将返回文档中所有的键。别的键说明符都是默认不返回未提及的键,这点与"$slice"不太一样。

根据上面的阐述我作了下面的试验

> db.blog.posts.insert({"title":"A blog post","content":"...","comments":["aa","bb","cc","dd"]})
> db.blog.posts.findOne({"title":"A blog post"},{"comments":{"$slice":2}})
{
        "_id" : ObjectId("5194360f2dd15cb60ff86f37"),
        "title" : "A blog post",
        "content" : "...",
        "comments" : [
                "aa",
                "bb"
        ]
}

的确是将所有的键都返回了,但难道不是所有键说明符都这样吗?请前辈举个例子:)


2 回复

Node.js MongoDB:关于“使用 $slice 时将返回文档中所有的键”

概述

在 MongoDB 中,使用 $slice 操作符时,它会返回数组中的指定元素,但同时也会返回文档中的其他所有键。这与使用其他键说明符(如 $elemMatch 或直接指定键名)的行为不同,后者只返回明确提到的键。

示例代码

让我们通过一个具体的例子来理解这一点。假设我们有一个博客文章集合 blog.posts,其中每篇博客文章都有一个 comments 字段,该字段包含多个评论。

const { MongoClient } = require('mongodb');

async function run() {
    const uri = "your_mongodb_connection_string";
    const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

    try {
        await client.connect();
        const database = client.db('testdb');
        const collection = database.collection('blog.posts');

        // 插入一条测试数据
        await collection.insertOne({
            title: "A blog post",
            content: "...",
            comments: ["aa", "bb", "cc", "dd"]
        });

        // 使用 $slice 查找文档并返回指定数量的评论
        const result = await collection.findOne(
            { title: "A blog post" },
            { comments: { $slice: 2 } }
        );

        console.log(result);
    } finally {
        await client.close();
    }
}

run().catch(console.dir);

输出结果

执行上述代码后,输出结果将是:

{
    "_id": "some_object_id_value",
    "title": "A blog post",
    "content": "...",
    "comments": [
        "aa",
        "bb"
    ]
}

解释

从输出结果可以看出,尽管我们只指定了 $slice 操作符来获取 comments 数组中的前两个元素,但整个文档的其他键(如 _id, title, content)也被一并返回了。这就是题目所述的情况:使用 $slice 时,MongoDB 会返回文档中所有存在的键,而不仅仅是 $slice 指定的键。

总结

  • 使用 $slice 操作符时,MongoDB 会返回文档中所有的键。
  • 其他键说明符(如 $elemMatch 或直接指定键名)则只返回明确提到的键。
  • 如果你需要仅返回部分键,可以考虑使用投影(projection)来明确指定需要返回的键。

希望这个示例能帮助你更好地理解 $slice 的行为。


根据你的描述,在MongoDB中使用 $slice 操作符时,默认情况下会返回整个文档,而不仅仅是指定字段的部分内容。这与普通的投影(projection)操作符不同,后者只返回明确提到的字段。

为了仅返回指定字段的部分内容,你需要在查询中明确指定需要返回的字段。下面是一些示例代码来演示如何做到这一点:

示例代码

const MongoClient = require('mongodb').MongoClient;
const uri = "your_mongodb_connection_string";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

async function run() {
    try {
        await client.connect();
        const database = client.db('testdb');
        const collection = database.collection('posts');

        // 插入示例数据
        await collection.insertOne({
            "title": "A blog post",
            "content": "...",
            "comments": ["aa", "bb", "cc", "dd"]
        });

        // 使用 $slice 操作符仅返回指定字段的部分内容
        const result = await collection.findOne(
            { "title": "A blog post" }, 
            { "comments": { "$slice": 2 } }
        );

        console.log(result);
    } finally {
        await client.close();
    }
}

run().catch(console.dir);

解释

  • 在这个示例中,我们首先连接到MongoDB数据库,并插入一条示例文档。
  • 然后,我们使用 findOne 方法查询文档。在第二个参数中,我们使用 { "comments": { "$slice": 2 } } 来限制只返回 comments 字段的前两个元素。
  • 最终输出结果仅包含 title, _id, 和部分 comments 字段,而不包含 content 字段。

通过这种方式,你可以确保在使用 $slice 操作符时只返回你所需要的字段部分,而不是整个文档。

回到顶部