**
Краткое резюме: приложение 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.
** Обновить **
Оказывается, что-то не так с моей обработкой строк. Без строковых полей в данных все нормально. Так что я как-то измотал свои строки, хотя они выглядят и ведут себя правильно, в других отношениях они не очень хорошо работают с конвейером агрегации. Я использую mongocxx :: collection.bulk_write для написания стандартных строк std ::, которые загружаются с сервера sql через заголовок OTL4. Между ними есть strncpy_s, когда они хранятся внутри. Я не могу создать простой воспроизводимый пример.
Просто чтобы быть уверенным, что нет конфликта с чем-либо еще, попробуйте использовать проекцию со строго отформатированным json: (добавьте кавычки к ключам)
db.TemporaryData.aggregate( [ { $project : { "ParametersId":1, "Col1":1 } } ] )
Наконец обнаружил, что проблема в поврежденных документах, которые из-за того, что я использовал bulk_write для вставки, попадали в базу данных, но вызывали это странное поведение. Я переключился на использование insert_many, которое вырвало документ поврежденным, и затем я смог отследить ошибку.
Документы были повреждены, потому что я записывал одни и те же данные значения поля несколько раз, что, кажется, нарушает bsoncxx :: builder :: stream :: document, который я использовал для их создания.