【问题标题】:MongoDB Limit fields and slice projection togetherMongoDB 限制字段和切片投影在一起
【发布时间】:2014-07-11 08:08:23
【问题描述】:

我有以下用户对象:

{
  "_id" : ObjectId("someId"),
  "name" : "Bob",
  "password" : "fakePassword",
  "follower" : [...],
  "following" : [..]
}

我需要对关注者列表进行分页,所以我使用切片投影运算符,但我只需要返回分页关注者列表。而且我不知道我是否以错误的方式进行操作,或者无法做到,但是限制字段不适用于切片投影。

以下是我尝试的几个查询:

 collection.findOne(
          {
            _id: new ObjectId(userId)
          },
          {
            follower: {$slice:[skip, parseInt(pageSize)]},
            follower: 1
          },..

collection.findOne(
          {
            _id: new ObjectId(userId)
          },
          {
            follower: 1,
            follower: {$slice:[skip, parseInt(pageSize)]}
          },

但是这些返回对象中的所有值,并且不限制字段,尽管切片在这两种情况下都可以正常工作。 此外,当我执行 _id:0,following:0 之类的操作时,这部分工作,但我不想像这样提及查询中的每个字段,一旦我决定更改架构,它可能会产生问题。 我该如何让它工作,查询的语法是什么才能让它工作..??

【问题讨论】:

    标签: javascript node.js mongodb mongoose mongodb-query


    【解决方案1】:

    不确定我是否在此处了解您的使用模式。也许我们可以稍微简化一下这个例子。所以考虑文件:

    {
        "_id" : ObjectId("537dd763f95ddda3208798c5"),
        "name" : "Bob",
        "password" : "fakePassword",
        "follower" : [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F",
                "G",
                "H",
                "I",
                "J",
                "K"
        ]
    }
    

    所以像这样的简单查询:

    db.paging.find(
        { "name": "Bob" },
        { 
            "_id": 0, 
            "name": 0, 
            "password": 0, 
            "follower": { "$slice": [0,3] } 
    }).pretty()
    

    给出结果:

    {
        "follower" : [
                "A",
                "B",
                "C"
        ]
    }
    

    同样来自以下页面:

    db.paging.find(
        { "name": "Bob" },
        { 
            "_id": 0, 
            "name": 0, 
            "password": 0, 
            "follower": { "$slice": [3,3] } 
    }).pretty()
    

    给出结果:

    { 
        "follower" : [ 
            "D", 
            "E", 
            "F" 
        ]
    }
    

    因此,就我个人而言,我不确定您是在询问字段排除还是您是否在询问“分页”数组结果,但无论哪种方式,这两个示例都显示在此处。

    【讨论】:

    • 所以就像在你的回答中一样,你必须定义你需要删除的所有字段,但是根据 mongodb 文档,你也可以只指定你需要的字段,比如followers:1,所以这只会给我 followers 字段和 _id 字段,我不必指定我不需要的所有其他字段。我需要它来使用切片投影运算符。
    • @SambhavSharma 如果这是您的实际问题,那么我会很高兴地提交文档补丁(已经是贡献者),但实际上这种方式不起作用。使用$slice 时,您需要明确排除所有不需要的字段。您也不能在 .find() 下混合包含和排除,如果您需要这种复杂性,那么您可以使用 .aggregate()$project 运算符。
    【解决方案2】:

    一种方法是在这里通过{_id:1} 实际使用_id:

    { "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2"), "f" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20 ], "d" : 1 }
    > db.test.findOne({ "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2")},{f:{$slice:[0,2]}})
    {
            "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2"),
            "f" : [
                    1,
                    2
            ],
            "d" : 1
    }
    > db.test.findOne({ "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2")},{_id:0, f:{$slice:[0,2]}})
    { "f" : [ 1, 2 ], "d" : 1 }
    > db.test.findOne({ "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2")},{_id:1, f:{$slice:[0,2]}})
    { "_id" : ObjectId("537de1bc08eb9d89a7d3a1b2"), "f" : [ 1, 2 ] }
    

    【讨论】:

    • 我认为这应该被标记为正确答案。此外,如果您绝对不想要 _id,您可以设置 _id: 0 和一些不存在的_field: 1。但在返回的文档中包含 _id 似乎不太可能成为问题。还有一件事;如果您要在 sub_doc.my_array: {$slice ...} 之类的子文档中切片,则需要在该级别选择一个不存在的字段,例如 sub_doc.nonexistant_field: 1 以防止获得的不仅仅是切片
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-14
    • 2015-12-19
    • 2015-06-06
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2015-04-01
    相关资源
    最近更新 更多