C ++ пишет в монго, строковые поля не работают в конвейере агрегации - PullRequest
0 голосов
/ 30 декабря 2018

** Краткое резюме: приложение C ++, загружающее данные с сервера SQL с использованием OTL4, записывающее в Mongo с помощью mongocxx bulk_write, кажется, что строки каким-то образом искажаются, поэтому они не работают в конвейере агрегации (но в противном случае выглядят нормально).**

У меня есть простая коллекция 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 lib.

** update **

Оказывается, что-то не так с моей обработкой строк.Без строковых полей в данных все в порядке.Поэтому я как-то измотал свои строки, даже если они выглядят и ведут себя правильно, в других отношениях они не очень хорошо работают с конвейером агрегации.Я использую mongocxx :: collection.bulk_write для написания стандартных строк std ::, которые загружаются с сервера sql через заголовок OTL4.Между ними есть strncpy_s, когда они хранятся внутри.Я не могу создать простой воспроизводимый пример.

Ответы [ 2 ]

0 голосов
/ 01 января 2019

Наконец-то выяснилось, что проблема в поврежденных документах, которые из-за того, что я использовал bulk_write для вставки, попадали в базу данных, но вызывали это странное поведение.Я переключился на использование insert_many, которое вырвало документ поврежденным, и затем я смог отследить ошибку.

Документы были повреждены, потому что я записывал одни и те же данные значения поля несколько раз, что, кажется, нарушает bsoncxx :: builder :: stream :: document, который я использовал для их создания.

0 голосов
/ 31 декабря 2018

Просто чтобы быть уверенным, что нет конфликта с чем-либо еще, попробуйте использовать проекцию со строго отформатированным json: (добавить кавычки к ключам)

db.TemporaryData.aggregate( [ { $project :  {  "ParametersId":1, "Col1":1 } } ] )
...