草庐IT

mongodb - Cosmos DB 聚合管道不兼容(Mongo API)?

coder 2023-10-31 原文

也许有人知道我们如何修复或变通一些看起来像 Azure Cosmos DB 中 MongoDB 聚合管道当前实现中的错误的东西(所以是的:我们已经在我们的实例上打开了该功能)。

简短的版本是:在我们看来 $match聚合阶段之后一个$group阶段不起作用。它从不返回任何结果。

假设您已经在一个有效的数据库中(使用 use <some db>),这可以使用任何 Mongo 控制台以下列方式重现:

粘贴以下 JavaScript(如果您通过 Azure 门户创建集合,则此行是可选的;它假定您的集合名为 bug)

db.createCollection("bug");

向集合中添加一些文档:

db.bug.insert({ _id: 1, owner: "a", _class: "History" });
db.bug.insert({ _id: 2, owner: "a", _class: "History" });
db.bug.insert({ _id: 3, owner: "a", _class: "DocumentBookmark" });
db.bug.insert({ _id: 4, owner: "a", _class: "Recyclebin" });
db.bug.insert({ _id: 5, owner: "b", _class: "History" });

如您所见,owner: "a"有重复的 History记录,我们要查询。

现在执行以下操作:

db.bug.aggregate([
    { $match: { _class: "History"} }
]);

这会呈现正确的结果:

globaldb:PRIMARY> db.bug.aggregate([
...     { $match: { _class: "History"} }
... ]);
{
    "_t" : "AggregationPipelineResponse",
    "ok" : 1,
    "waitedMS" : NumberLong(0),
    "result" : [
        {
            "_id" : 1,
            "owner" : "a",
            "_class" : "History"
        },
        {
            "_id" : 2,
            "owner" : "a",
            "_class" : "History"
        },
        {
            "_id" : 5,
            "owner" : "b",
            "_class" : "History"
        }
    ]
}

现在添加一个$group舞台 count查找每个所有者的记录数:

db.bug.aggregate([
    { $match: { _class: "History"} },
    { $group: { _id: "$owner", count: { $sum: 1 }}}
]);

这也会返回正确的结果:

globaldb:PRIMARY> db.bug.aggregate([
...     { $match: { _class: "History"} },
...     { $group: { _id: "$owner", count: { $sum: 1 }}}
... ]);
{
    "_t" : "AggregationPipelineResponse",
    "ok" : 1,
    "waitedMS" : NumberLong(0),
    "result" : [
        {
            "_id" : "a",
            "count" : NumberLong(2)
        },
        {
            "_id" : "b",
            "count" : NumberLong(1)
        }
    ]
}

现在我们要匹配 count 的记录大于 1:

db.bug.aggregate([
    { $match: { _class: "History"} },
    { $group: { _id: "$owner", count: { $sum: 1 }}},
    { $match: { count: { $gt: 1 }}}
]);

这将返回一个结果集:

globaldb:PRIMARY> db.bug.aggregate([
...     { $match: { _class: "History"} },
...     { $group: { _id: "$owner", count: { $sum: 1 }}},
...     { $match: { count: { $gt: 1 }}}
... ]);
{
    "_t" : "AggregationPipelineResponse",
    "ok" : 1,
    "waitedMS" : NumberLong(0),
    "result" : [ ]
}

在 Mongo DB 上也是如此

现在,为了验证这些查询是否确实正确,我使用 mongo:3.4 进行了尝试码头图像。以下代码将在您的本地计算机上启动一个新的 Mongo DB 实例,以便您可以自己尝试:

$ docker run --name mongobug -d mongo:3.4
ad3010da255b7c15a464fa21ff6519799a5c16cb8af62a0ea564a95780900491
$ docker exec -it mongobug mongo
MongoDB shell version v3.4.10
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.10
Welcome to the MongoDB shell.
>

然后我们将执行与上面 Cosmos 相同的操作;在 Mongo Shell 中,运行以下命令:

db.createCollection("bug")

然后插入测试数据:

db.bug.insert({ _id: 1, owner: "a", _class: "History" });
db.bug.insert({ _id: 2, owner: "a", _class: "History" });
db.bug.insert({ _id: 3, owner: "a", _class: "DocumentBookmark" });
db.bug.insert({ _id: 4, owner: "a", _class: "Recyclebin" });
db.bug.insert({ _id: 5, owner: "b", _class: "History" });

现在您可以看到返回空集的查询在运行以下聚合查询时实际上返回了一个非空聚合结果:

db.bug.aggregate([
    { $match: { _class: "History"} },
    { $group: { _id: "$owner", count: { $sum: 1 }}},
    { $match: { count: { $gt: 1 }}}
]);

结果是预期的:

> db.bug.aggregate([
...     { $match: { _class: "History"} },
...     { $group: { _id: "$owner", count: { $sum: 1 }}},
...     { $match: { count: { $gt: 1 }}}
... ]);
{ "_id" : "a", "count" : 2 }

阅读额外奖励

我还尝试按 owner 分组和 _class在联合小组中然后$match ;这显然是一个更昂贵的操作,因为 Mongo 必须对整个集合进行分组,而不仅仅是对已经过滤的项目进行分组。

但是,不幸的是,当它在本地 Mongo docker 图像上工作时,这也呈现了一个空结果:

db.bug.aggregate([
    { $group: { _id: { owner: "$owner", _class: "$_class" }, count: { $sum: 1 } } },
    { $match: { "_id._class": "History", count: { $gt: 1 } } }
]);

Cosmos 上的结果:

globaldb:PRIMARY> db.bug.aggregate([
...     { $group: { _id: { owner: "$owner", _class: "$_class" }, count: { $sum: 1 } } },
...     { $match: { "_id._class": "History", count: { $gt: 1 } } }
... ]);
{
    "_t" : "AggregationPipelineResponse",
    "ok" : 1,
    "waitedMS" : NumberLong(0),
    "result" : [ ]
}

Mongo DB 上的结果:

> db.bug.aggregate([
...     { $group: { _id: { owner: "$owner", _class: "$_class" }, count: { $sum: 1 } } },
...     { $match: { "_id._class": "History", count: { $gt: 1 } } }
... ]);
{ "_id" : { "owner" : "a", "_class" : "History" }, "count" : 2 }

奇怪。

tl;博士

Cosmos DB 是否存在不允许运行的错误 $match$group 之后聚合阶段?

最佳答案

自 Azure Cosmos DB for MongoDB API 版本 3.6 发布以来,我想为此线程提供更新,聚合问题现在返回正确的结果。

初始查询 + 结果:

db.coll_01.aggregate([
  { $match: { _class: "History"} }
    ]);

Operation consumed 3.18 RUs
{ "_id" : 1, "owner" : "a", "_class" : "History" }
{ "_id" : 2, "owner" : "a", "_class" : "History" }
{ "_id" : 5, "owner" : "b", "_class" : "History" }

第二个查询+结果:

db.coll_01.aggregate([
 { $match: { _class: "History"} },
 { $group: { _id: "$owner", count: { $sum: 1 }}}
   ]);

Operation consumed 3.36 RUs
{ "_id" : "a", "count" : 2 }
{ "_id" : "b", "count" : 1 }

最后是聚合查询+结果:

db.coll_01.aggregate([
 { $match: { _class: "History"} },
 { $group: { _id: "$owner", count: { $sum: 1 }}},
 { $match: { count: { $gt: 1 }}}
  ]);

Operation consumed 3.36 RUs
{ "_id" : "a", "count" : 2 }

更多信息请查看:Azure Cosmos DB's API for MongoDB (3.6 version): supported features and syntax

关于mongodb - Cosmos DB 聚合管道不兼容(Mongo API)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48381501/

有关mongodb - Cosmos DB 聚合管道不兼容(Mongo API)?的更多相关文章

  1. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  2. ruby-on-rails - 不兼容的库版本 : nokogiri. bundle 需要 8.0.0 或更高版本,但 libiconv.2.dylib 提供 7.0.0 版本 - 2

    为了在我的mac上为一个rails项目安装mysql,我遵循了安装Homebrew软件和删除mac端口的在线建议。这是问题开始的地方。rails项目不会构建,我得到这个:[rake--prereqs]rakeaborted!dlopen(/Users/Parker/.rvm/gems/ruby-1.9.3-p448/gems/nokogiri-1.6.0/lib/nokogiri/nokogiri.bundle,9):Librarynotloaded:/opt/local/lib/libiconv.2.dylibReferencedfrom:/Users/Parker/.rvm/gem

  3. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  4. ruby - Rails Elasticsearch 聚合 - 2

    不知何故,我似乎无法获得包含我的聚合的响应...使用curl它按预期工作:HBZUMB01$curl-XPOST"http://localhost:9200/contents/_search"-d'{"size":0,"aggs":{"sport_count":{"value_count":{"field":"dwid"}}}}'我收到回复:{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":90,"max_score":0.0,"hits":[]},"a

  5. c# - Ruby 等效于 C# Linq 聚合方法 - 2

    什么是Linq聚合方法的ruby​​等价物。它的工作原理是这样的varfactorial=new[]{1,2,3,4,5}.Aggregate((acc,i)=>acc*i);每次将数组序列中的值传递给lambda时,变量acc都会累积。 最佳答案 这在数学以及几乎所有编程语言中通常称为折叠。它是更普遍的变形概念的一个实例。Ruby从Smalltalk中继承了这个特性的名称,它被称为inject:into:(像aCollectioninject:aStartValueinto:aBlock一样使用。)所以,在Ruby中,它称为inj

  6. ruby - 用于 CSS3 跨浏览器兼容性的 SASS 插件? - 2

    是否有一个SASS扩展可以采用SASS样式表,找到中性属性(例如border-radius)并为其输出所有特定于供应商的属性(例如-webkit-border-radius等)自动?我真的不想手动创建所有混入,也不想手动编写代码。我确定一定有这样的扩展名,但我找不到它。帮忙? 最佳答案 有一个非常好的gem可以满足您的需求。它叫做Bourbon它不会用特定于供应商的css替换您的css,因为它可以像SASS一样工作。它基本上是一个正确生成跨浏览器css的mixin集合。 关于ruby-用

  7. ruby - 我在哪里可以找到与其兼容的 Ruby 版本的 gems 版本号? - 2

    这个问题说明了一切。例如,我有一台安装了ruby​​1.8.6的服务器。当我尝试sudogeminstallroo时,它给出了错误nokogirirequiresRubyversion>=1.8.7。所以,我想安装与Ruby1.8.6兼容的旧版本roo。但我不知道去哪里搜索。我知道RubyForge,但它也没有说明Ruby的兼容版本。 最佳答案 蛮力方法是获取一个git克隆,搜索它指定的Ruby版本的位置,然后使用gitblame甚至gitpickaxe来确定最后一个没有的版本'没有那个要求。

  8. ruby - Jekyll 与 .erb 的兼容性 - 2

    据我了解,Jekyll兼容Liquid和YAML。但是,是否有插件或可用功能可以使其与.erb(嵌入式Ruby)文件兼容?否则,这是一个不必要的功能还是没有用的东西?Jekyll对Liquid和YAML的内置使用是否会取代.erb将会或可以做什么?谢谢! 最佳答案 使用.erb不适合jekyll,但是你应该使用jekyll-renderinggem。 关于ruby-Jekyll与.erb的兼容性,我们在StackOverflow上找到一个类似的问题: http

  9. ruby - ruby 命令行开关 -rubygems & -r 不兼容吗? - 2

    我最近将一个ruby​​库转换为一个gem,这似乎破坏了命令行的可用性作为图书馆工作得很好$ruby-rfoobar-e'pFooBar.question'#=>"answer"作为一个gem,irb知道如何从命令行开关中请求一个gem$irb-rubygems-rfoobarirb(main):001:0>FooBar.question#=>"answer"但对于ruby​​本身来说同样失败了:$ruby-rubygems-rfoobar-e'pFooBar.question'ruby:nosuchfiletoload--foobar(LoadError)我现在必须这样做吗,这看起来

  10. ruby-on-rails - 如何通过 Assets 管道加载css.erb文件 - 2

    我希望我的样式表保持纯css,但我想使用嵌入式ruby​​来包含一些图像的动态路径:.home{background:#FFFurl()no-repeat;}如果我将样式表从.css更改为.css.erb,image_path会得到正确解释,但当我部署到生产环境时,它不会被Assets管道处理。如果我硬编码路径,无论是在生产还是开发中都会出错,因为它们以不同的方式加载Assets。我该如何解决? 最佳答案 这是有效的:将.erb添加到.css文件并使用ruby/rails代码就可以了。所以我上面的问题中的片段很好。你必须在/conf

随机推荐