【问题标题】:How to $pull embedded documents that are not in a given list from a Mongo collection?如何从 Mongo 集合中 $pull 不在给定列表中的嵌入文档?
【发布时间】:2011-12-08 05:41:04
【问题描述】:

我有一个名为文档的 Mongo 集合,其结构如下:

{
  name: "..."
  tokens: [
    {
       _id: <string (unique)>,
       tf: <integer>,
       tf_idf: <float>
    },
    ...
  ]
}

我有一个我想保留的令牌列表。是否有可能使用$pull 构建查询以删除列表中不包含 id 的所有令牌?

以下不起作用:

db.documents.update({name: "foo"}, { 
   $pull : { 
       $not : {
           $elemMatch : { 'tokens' : { '_id' : ['foo', 'bar'] }}
       }
   }
})

到目前为止,我看到的唯一选择是遍历所有文档并检查客户端是否保留令牌并最终将它们一一删除。我宁愿使用一种不涉及将所有数据拉到客户端的方法,只是为了检查哪些令牌可以删除,哪些不能。

【问题讨论】:

    标签: mongodb pull


    【解决方案1】:

    让我们考虑一下这些数据:

    > db.nicolas.find()
    { "_id" : ObjectId("4edfd6551757be3330db7c75"), 
              "tokens" : [ { "id" : 1 }, { "id" : 2 }, { "id" : 3 } ] }
    { "_id" : ObjectId("4edfd50452d5d16ccc1aa7b5"), 
              "tokens" : [ { "id" : 3 }, { "id" : 4 }, { "id" : 5 } ] }
    

    如果我应用这些转换:

    > db.nicolas.update({_id: ObjectId("4edfd6551757be3330db7c75")}, 
                        {$pull:{tokens: { id :{$nin:[1,2]}} } })
    

    我会得到以下内容:

    > db.nicolas.find()
    { "_id" : ObjectId("4edfd6551757be3330db7c75"), 
              "tokens" : [ { "id" : 1 }, { "id" : 2 } ] }
    { "_id" : ObjectId("4edfd50452d5d16ccc1aa7b5"), 
              "tokens" : [ { "id" : 3 }, { "id" : 4 }, { "id" : 5 } ] }
    

    所以,对于你的情况,这样的事情应该可以工作:

    > db.documents.update({name: "foo"}, 
                          {$pull: {tokens: { _id : {$nin:['foo','bar']}} } }) 
    

    有用吗?

    【讨论】:

      【解决方案2】:

      如果我理解正确,您只想保留 _id 值与“foo”或“bar”匹配的标记,对吗?

      给定集合:

      > db.test.find()
      { 
      "_id" : 1, 
      "name" : "Doc1", 
      "tokens" : [    
          { 
          "_id" : "foo",
          "tf" : 1,
          "tf_idf" : 1 
          },  
          {
          "_id" : "buzz",
          "tf" : 2,
          "tf_idf" : 2 
          } 
      ]
      },
      { 
      "_id" : 2, 
      "name" : "Doc2", 
      "tokens" : [    
          {
          "_id" : "bar",
          "tf" : 3,
          "tf_idf" : 3 
          },
          {
          "_id" : "bing",
          "tf" : 4,
          "tf_idf" : 4 
          }
      ]
      }
      

      以下更新应该可以完成您想要做的事情。这将从每个文档的 "tokens" 数组中删除 _id 值与 "foo" 或 "bar" 匹配的所有子文档。

      > db.test.update({}, {$pull:{tokens:{_id:{$nin:["foo", "bar"]}}}}, false, true)
      > db.test.find()
      { "_id" : 1, "name" : "Doc1", "tokens" : [ { "_id" : "foo", "tf" : 1, "tf_idf" : 1 } ] }
      { "_id" : 2, "name" : "Doc2", "tokens" : [ { "_id" : "bar", "tf" : 3, "tf_idf" : 3 } ] }
      

      关于 $pull 操作符的 Mongo 文档可以在这里找到: http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull

      希望这将帮助您做您需要做的事情。祝你好运!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-18
        • 1970-01-01
        • 2021-03-28
        • 1970-01-01
        • 1970-01-01
        • 2018-05-27
        • 1970-01-01
        • 2011-05-15
        相关资源
        最近更新 更多