Mongodb Node.js selectively $replaceRoot based on document member

Viewed 13

I have Mongodb documents which each include a 'geo' field with RFC7946-ish GeoJSON data. Depending on the complexity, simple items have a type 'Feature':

geo { 
  properties: {"name": "simpleItem"},
  type: "Feature",
  geometry: { ... }
}

other more complex items are type: "FeatureCollection":

geo: { 
  type: "FeatureCollection",
  features: 
  [ 
    { 
      properties: {"name": "complexItemSubfeature1"},
      type: "Feature",
      geometry: { ... }
    },
    { 
      properties: {"name": "complexItemSubfeature2"},
      type: "Feature",
      geometry: { ... }
    },
    ...
  ]
}

I want to flatten these into a final aggregated document as a single "FeatureCollection":

geo: { type: "FeatureCollection",
  features: 
  [ { 
      properties: {"name": "simpleItem"},
      type: "Feature",
      geometry: { ... }
    },
    { 
      properties: {"name": "complexItemSubfeature1"},
      type: "Feature",
      geometry: { ... }
    },
    { 
      properties: {"name": "complexItemSubfeature2"},
      type: "Feature",
      geometry: { ... }
    },
    ...
  ]
}

My approach is to selectively apply $replaceRoot depending on the value of "type" in each input document. However, $strcasecmp is not behaving as expected in a conditional expression. I have these two stages in my pipeline, which are part of a lookup:

...
{ $replaceRoot: {
    newRoot: { $cond: {if: { $eq: [{ $strcasecmp: ["$type", "FeatureCollection"] }, 0] },
                       then: "$geo.features",
                       else: "$geo"
                       }
              } } },
{ $addFields: {"geotype": "$type"}}
...
as "geo.features"

Which produces the following output. In the addFields stage I can clearly see the value of '$type', but $strcasecmp is never equating it to "FeatureCollection" as I would expect for the second document... help me understand what's going on!

(I'll add a trivial AddFields to include the type: "FeatureCollection" to the geo object once this works...)

geo: { 
  features: 
  [ { 
      properties: {"name": "simpleItem"},
      type: "Feature",
      geometry: { ... },
      geotype: "Feature"
    },
    { 
      type: "FeatureCollection",
      features: 
      [ 
        { 
          properties: {"name": "complexItemSubfeature1"},
          type: "Feature",
          geometry: { ... }
        },
        { 
          properties: {"name": "complexItemSubfeature2"},
          type: "Feature",
          geometry: { ... }
        },
        ...
      ],
      geotype: "FeatureCollection"
    }
  ]
}
0 Answers
Related