MongoDB (JS), do query opperations on one document property if available, else take other property

Tags: , , ,



So let’s say I have following documents in my “Request” collection:

{
  pickup: {
    coords: null
  },
  meetup: {
    coords: [ someLng, someLat ]
  }
},
{
  pickup: {
    coords: null
  },
  meetup: {
    coords: [ someLng, someLat ]
  }
},
{
  pickup: {
    coords: [ someLng, someLat ]
  },
  meetup: {
    coords: [ someLng, someLat ]
  }
}

The goal is to diplay to the user a sorted list of requests by distance from his position from nearest to farest.

If pickup.coords is available it should take that as position reference for follow up expressions, else take meetup.coords.

I tried using $cond but I get an error and I’m not sure how to use it exactly.

Here is what I thought could work:

const query = {
  $cond: {
    if: {
     'pickup.coords': { $exists: true }
    },
    then: {
      // use pickup.coords as reference for distance to user
    },
    else: {
      // use meetup.coords as reference for distance to user
    }
  }
}

const requests = await Request.find( query )

Error: unknown top level operator: $cond

The request will be much more complicated at the end, because I will do some pagination with limit and use $near operator with some indexing I think. But it would be nice to get this first step done 🙂

Any help would be greatly appreciated!

Answer

Modify your application to insert documents in format that supports your queries. Add one more field that contains coordinates you are going to search on:

{
    pickup: {
      coords: null
    },
    meetup: {
      coords: [ someLng, someLat ]
    },
    _search: {
      coords: [ someLng, someLat ]  
    }
  },
  {
    pickup: {
      coords: null
    },
    meetup: {
      coords: [ someLng1, someLat1 ]
    },
    _search: {
        coords: [ someLng1, someLat1 ]
    }
  },
  {
    pickup: {
      coords: [ someLng2, someLat2 ]
    },
    meetup: {
      coords: [ someLng3, someLat3 ]
    },
    _search: {
        coords: [ someLng2, someLat2 ]
    }
  }

Index on this field:

db.collection.createIndex( { _search : "2dsphere" } )

Search on this field:

db.collection.find(
   {
     _search: {
        $nearSphere: {
           $geometry: {
              type : "Point",
              coordinates : [  someLng4, someLat4 ]
           }
        }
     }
   }
)


Source: stackoverflow