C ++写入mongo,字符串字段在聚合管道中不起作用
Posted
技术标签:
【中文标题】C ++写入mongo,字符串字段在聚合管道中不起作用【英文标题】:C++ writing to mongo, string fields not working in aggregation pipeline 【发布时间】:2018-12-30 18:16:21 【问题描述】:** 快速总结:C++ 应用程序使用 OTL4 从 SQL 服务器加载数据,使用 mongocxx bulk_write 写入 Mongo,字符串似乎以某种方式被破坏,因此它们在聚合管道中不起作用(但在其他情况下看起来很好)。 **
我有一个简单的 Mongo 集合,当我投影多个字段时,它似乎与聚合管道的行为不符。这是一个简单的文档,没有嵌套,字段只是双精度和字符串。
前 2 个查询按预期工作:
> db.TemporaryData.aggregate( [ $project : ParametersId:1 ] )
"_id" : ObjectId("5c28f751a531251fd0007c72"), "ParametersId" : 526988617
"_id" : ObjectId("5c28f751a531251fd0007c73"), "ParametersId" : 526988617
"_id" : ObjectId("5c28f751a531251fd0007c74"), "ParametersId" : 526988617
"_id" : ObjectId("5c28f751a531251fd0007c75"), "ParametersId" : 526988617
"_id" : ObjectId("5c28f751a531251fd0007c76"), "ParametersId" : 526988617
> db.TemporaryData.aggregate( [ $project : Col1:1 ] )
"_id" : ObjectId("5c28f751a531251fd0007c72"), "Col1" : 575
"_id" : ObjectId("5c28f751a531251fd0007c73"), "Col1" : 579
"_id" : ObjectId("5c28f751a531251fd0007c74"), "Col1" : 616
"_id" : ObjectId("5c28f751a531251fd0007c75"), "Col1" : 617
"_id" : ObjectId("5c28f751a531251fd0007c76"), "Col1" : 622
但随后组合不会按预期返回两个字段。
> db.TemporaryData.aggregate( [ $project : ParametersId:1, Col1:1 ] )
"_id" : ObjectId("5c28f751a531251fd0007c72"), "ParametersId" : 526988617
"_id" : ObjectId("5c28f751a531251fd0007c73"), "ParametersId" : 526988617
"_id" : ObjectId("5c28f751a531251fd0007c74"), "ParametersId" : 526988617
"_id" : ObjectId("5c28f751a531251fd0007c75"), "ParametersId" : 526988617
"_id" : ObjectId("5c28f751a531251fd0007c76"), "ParametersId" : 526988617
它似乎特定于 ParametersId 字段,例如,如果我选择 2 个其他字段就可以了。
> db.TemporaryData.aggregate( [ $project : Col1:1, Col2:1 ] )
"_id" : ObjectId("5c28f751a531251fd0007c72"), "Col1" : 575, "Col2" : "1101-2"
"_id" : ObjectId("5c28f751a531251fd0007c73"), "Col1" : 579, "Col2" : "1103-2"
"_id" : ObjectId("5c28f751a531251fd0007c74"), "Col1" : 616, "Col2" : "1300-3"
"_id" : ObjectId("5c28f751a531251fd0007c75"), "Col1" : 617, "Col2" : "1300-3"
"_id" : ObjectId("5c28f751a531251fd0007c76"), "Col1" : 622, "Col2" : "1400-3"
由于某种原因,当我包含 ParametersId 字段时,管道中的一切都变得松散了:
> db.TemporaryData.aggregate( [ $project : ParametersId:1, Col2:1, Col1:1, Col3:1 ] )
"_id" : ObjectId("5c28f751a531251fd0007c72"), "ParametersId" : 526988617, "Col1" : 575
"_id" : ObjectId("5c28f751a531251fd0007c73"), "ParametersId" : 526988617, "Col1" : 579
"_id" : ObjectId("5c28f751a531251fd0007c74"), "ParametersId" : 526988617, "Col1" : 616
"_id" : ObjectId("5c28f751a531251fd0007c75"), "ParametersId" : 526988617, "Col1" : 617
"_id" : ObjectId("5c28f751a531251fd0007c76"), "ParametersId" : 526988617, "Col1" : 622
数据库版本和数据:
> db.version()
4.0.2
> db.TemporaryData.find()
"_id" : ObjectId("5c28f751a531251fd0007c72"), "CellId" : 998909269, "ParametersId" : 526988617, "Order" : 1, "Col1" : 575, "Col2" : "1101-2", "Col3" : "CHF"
"_id" : ObjectId("5c28f751a531251fd0007c73"), "CellId" : 998909269, "ParametersId" : 526988617, "Order" : 1, "Col1" : 579, "Col2" : "1103-2", "Col3" : "CHF"
"_id" : ObjectId("5c28f751a531251fd0007c74"), "CellId" : 998909269, "ParametersId" : 526988617, "Order" : 1, "Col1" : 616, "Col2" : "1300-3", "Col3" : "CHF"
"_id" : ObjectId("5c28f751a531251fd0007c75"), "CellId" : 998909269, "ParametersId" : 526988617, "Order" : 36, "Col1" : 617, "Col2" : "1300-3", "Col3" : "CHF"
"_id" : ObjectId("5c28f751a531251fd0007c76"), "CellId" : 998909269, "ParametersId" : 526988617, "Order" : 1, "Col1" : 622, "Col2" : "1400-3", "Col3" : "CHF"
更新:引用字段名称没有区别。我在 mongo.exe 命令行中输入了以上所有内容,但我在 C++ 应用程序中看到了相同的行为,但管道稍微复杂一些(投影所有字段以保证顺序)。
这个应用程序实际上首先创建了数据 - 有谁知道可能出错的地方吗?全部使用 mongocxx 库。
** 更新**
原来我对字符串的处理出了点问题。没有数据中的字符串字段,一切都很好。因此,不知何故,我已经弄坏了我的字符串,即使它们在其他方面看起来和行为正确,但它们不能很好地与聚合管道配合使用。我正在使用 mongocxx::collection.bulk_write 编写标准 std::strings,这些标准是通过 OTL4 标头从 sql server 加载的。当它们在内部存储时,中间有一个 strncpy_s 。我似乎无法创建一个简单的可重现示例。
【问题讨论】:
Col1 中可能隐藏了特殊字符,如果您正在复制/粘贴,请尝试手动输入 【参考方案1】:为了安全起见,不要与其他任何东西发生冲突,请尝试使用具有严格格式的 json 的投影:(为键添加引号)
db.TemporaryData.aggregate( [ $project : "ParametersId":1, "Col1":1 ] )
【讨论】:
谢谢 - 我刚刚尝试过,但没有任何区别。将更新问题。 我实际上在 3.6 中尝试过这个,我没有遇到任何投影问题。我使用相同的数据,带引号的查询。一切都按预期进行。 :(【参考方案2】:最后发现问题是文档损坏,因为我使用 bulk_write 进行插入进入数据库但导致了这种奇怪的行为。我切换到使用 insert_many,它抛出了文档已损坏,然后我可以追踪错误。
文档已损坏,因为我多次写入相同的字段值数据,这似乎破坏了我用来构造它们的 bsoncxx::builder::stream::document。
【讨论】:
以上是关于C ++写入mongo,字符串字段在聚合管道中不起作用的主要内容,如果未能解决你的问题,请参考以下文章