【问题标题】:Getting 'query in command must target a single shard'获取“命令中的查询必须针对单个分片”
【发布时间】:2018-10-11 05:48:18
【问题描述】:

我有一个使用 Mongo API 的 CosmosDB 设置。我在文档的一个字段上有一个带有散列碎片的集合。当我运行 db.collection.removedb.collection.deleteMany 之类的命令时,出现以下错误。

Command deleteMany failed: query in command must target a single shard key.: {"message":"Command deleteMany failed: query in command must target a single shard key."}

考虑到我希望查询跨所有分片运行,我不确定如何在查询中提及分片键。

【问题讨论】:

    标签: azure-cosmosdb azure-cosmosdb-mongoapi


    【解决方案1】:

    当您想运行db.collection.removedb.collection.deleteMany 等命令时,您需要提供shard key。

    例如:

    我的数据源如下:

    [
        {
            "id" : "2",
            "name" : "b"
        },
        {
            "id" : "1",
            "name" : "a"
        }
    ]
    

    我的共享密钥是"/name"。使用db.coll.deleteMany({"name":"a"}) 删除特定分片。

    希望对你有所帮助。

    【讨论】:

    • 感谢杰伊的回答。由于我有一个基于字段哈希的分片键,这是否意味着我必须先查询所有文档,才能获取该字段,然后使用该字段为它们调用 delete?
    • @Zabi 是的,我认为如果你无法获取它们,你需要先查询它们。
    • 谢谢,这是有道理的。只是如果我要删除与特定过滤器匹配的数百万条记录,我需要首先查询这些数百万条记录的分片字段,然后运行删除。有没有更好的办法?
    • 如果我有另一个文档 {id:3,name:"a"} 并且我想根据 id 删除它,我需要查询这两个参数,id(标识文件)和名称(因为它是一个分片键),对吧?
    【解决方案2】:

    应该是你创建 cosmosDb 集合时选择的 ShardKey。

    FilterDefinition<Product> filter = Builders<Product>.Filter.Eq("id", 2);
    === 2 是我的 shardKey

    await this._dbContext.GetProducts.DeleteOneAsync(filter);
    return RedirectToAction("Index");
    

    请参考下面的图片,它在 CosmosDB 中的样子

    【讨论】:

      【解决方案3】:

      Shard Key(Partition Key) 必须在代码中指定模式模型时提供。一旦提供,我们就可以像往常一样执行保存、更新和删除等常规操作。

      例子:

      const mySchema = new Schema({
          requestId: { type: String, required: true },
          data: String,
          documents: [{ docId: String, name: String, attachedBy: String }],
          updatedBy: {
              type: {
                  name: { type: String, required: true },
                  email: { type: String, required: true },
              }, required: true
          },
          createdDate: { type: Date, required: true },
          updatedDate: { type: Date },
      }, { shardKey: { requestId: 1 } }
      );
      

      在上面的代码中,我们指定 requestId 为 Shard Key,现在我们可以执行任何 mongo 操作 示例:

      let request:any = await myModel.findById(requestId);
      request.data ="New Data";
      await request.save();
      

      希望对您有所帮助。

      这适用于所有 Mongo 操作

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-30
        • 1970-01-01
        • 1970-01-01
        • 2021-02-19
        • 2017-03-27
        • 2017-04-05
        相关资源
        最近更新 更多