MongoDB BSONSerializer 添加额外的小数

问题描述 投票:0回答:1

我们有一个 C# 应用程序,它使用 C# 驱动程序创建 MongoDB 聚合查询。其中也有一些双值。

 var distanceScript = Properties.Resources.SEARCH_STEP2_ADD_DISTANCE;
 distanceScript = distanceScript.Replace("<LONGITUDE>", criteria.Location[0].ToString());
 distanceScript = distanceScript.Replace("<LATITUDE>", criteria.Location[1].ToString());
 var distanceDocument = new BsonDocument { { "$addFields", Utils.GetProjectQuery(distanceScript) } };


  public static BsonDocument GetProjectQuery(string queryPath)
  {
      return BsonSerializer.Deserialize<BsonDocument>(queryPath);
  }

但是当执行 GetProjectQuery(将字符串反序列化为 BsonDocument)时,它总是会在双精度值的末尾添加额外的小数。

例如:预期输出应该是:

{
                "geoWithin" : {
                    "circle" : {
                        "center" : {
                            "type" : "Point",
                            "coordinates" : [
                                58.3575487,
                                23.5880847
                            ]
                        },
                        "radius" : 15000
                    },
                    "path" : "Store.Location"
                }
            }

实际产量:

{
                "geoWithin" : {
                    "circle" : {
                        "center" : {
                            "type" : "Point",
                            "coordinates" : [
                                58.357548700000002,
                                23.5880847
                            ]
                        },
                        "radius" : 15000
                    },
                    "path" : "Store.Location"
                }
            }

知道为什么会这样以及我如何消除它。

c# mongodb mongodb-.net-driver bsondocument
1个回答
0
投票

通过本地调试,我注意到这些值被反序列化为

BsonDouble
,我认为这是
BsonSerializer
处理十进制/双精度值时的默认行为。

当您从 JSON 字符串进行反序列化时,自定义序列化程序和自定义序列化程序提供程序都不会处理十进制/双精度(反)序列化,除非您对上述类型的值进行(反)序列化。

因此,最快、最简单的方法(尽管这可能看起来很脏)是您应该在反序列化为

Decimal128
后通过用
BsonDocument
类型覆盖来对值进行后处理。

var distanceDocument = new BsonDocument { { "$addFields", Utils.GetProjectQuery(distanceScript) } };

distanceDocument["geoWithin"]["circle"]["center"]["coordinates"][0] 
    = new Decimal128(result["geoWithin"]["circle"]["center"]["coordinates"][0].ToDecimal());
distanceDocument["geoWithin"]["circle"]["center"]["coordinates"][1] 
    = new Decimal128(result["geoWithin"]["circle"]["center"]["coordinates"][1].ToDecimal());
© www.soinside.com 2019 - 2024. All rights reserved.