$geoNear pipeline to get all companies with all offices in range, including only those offices

I am trying to model companies that have multiple offices, each of which has a location. I need to return, for a given point, each company that has an office within range of that point and all the offices of those companies that are in range.

I’m looking for an output like:

[{
  "name": "Monkey Capital",
  "offices": [{
    "type": "branch",
    "loc": { "type": "Point", "coordinates": [...]},
    "distance": 6500,
  }],
}, {
  "name": "Magic Beef",
  "offices": [{
    "type": "branch",
    "loc": { "type": "Point", "coordinates": [...]}
    "distance": 3200
  }, {
    "type": "main",
    "loc": { "type": "Point", "coordinates": [...]}
    "distance": 4500
  }],
}]

First, I tried to put addresses on the company collection:

db.companiesWithOffices.insertMany([{
    name: "Monkey Capital",
    offices: [{
        loc: { type: "Point", "coordinates": [-74.007474, 40.727497] },
        type: "main",
    }, {
        loc: { type: "Point", "coordinates": [-89.985664, 38.593919] },
        type: "branch",
    }],
}, {
    name: "Magic Beef",
    offices: [{
        loc: { type: "Point", "coordinates": [-89.983199, 38.487439] },
        type: "main",
    }, {
        loc: { type: "Point", "coordinates": [-88.548630, 39.120455] },
        type: "branch",
    }],
}])

and query that with:

db.companiesWithOffices.aggregate([
  { "$geoNear": {
     "near": {type: "Point", "coordinates": [ -90.017688, 38.543353  ]},
     "spherical": true,
     "distanceField": "distance",
     "includeLocs": "locs",
     "maxDistance": 100000,
  }}
])

That works, gives me the document structure I want (company with nested locations), and only returns companies that have an office within the distance. However, the returned company documents contain all the office locations for that company, which is not helpful.

Next, I tried to unwind and redact offices:

db.companiesWithOffices.aggregate([
    {
        "$geoNear": {
            near: { "type": "Point", "coordinates": [-90.017688, 38.543353] },
            distanceField: "distance",
            maxDistance: 10000,
            includeLocs: "loc",
            spherical: true
        }
    },
    { "$unwind": "$offices" },
    {
        "$redact": {
            "$cond": {
                if: { "$eq": [{ "$cmp": ["$offices", "$loc"] }, 0] },
                then: "$$KEEP",
                else: "$$PRUNE"
            }
        }
    },
])

However, this only shows the nearest office for each company, not all company offices within range.

A bunch of Googling suggests what I’m looking for is not possible in this structure. because distance is calculated at the document (company) level.

Now, I’m trying this as two collections:

db.companies.insertMany([{
    "name": "Monkey Capital",
}, {
    "name": "Magic Beef",
}])

db.offices.insertMany([{
    "company_id": <id of MonkeyCapital>,
    "loc": { "type": "Point", "coordinates": [-74.007474, 40.727497] },
}, {
    "company_id": <id of MonkeyCapital>,
    "loc": { "type": "Point", "coordinates": [-89.985664, 38.593919] },
    "type": "branch"
}, {
    "company_id": <id of Magic Beef>,
    "loc": { "type": "Point", "coordinates": [-89.983199, 38.487439] },
    "type": "main",
}, {
    "company_id": <id of Magic Beef>,
    "loc": { "type": "Point", "coordinates": [-88.548630, 39.120455] },
    "type": "branch",
}

I’ve been trying to use $lookup and $geoNear in a pipeline, but can’t get the structure of document I need.

This example Querying with results from $geoNear is the close to my needs, but has the products a “children” of the stores, not “parent”.

This example Trying to use $geoNear inside $lookup pipeline appears to pull all from one collection.

Is the document structure I’m looking for achievable in a single query?