The is that you have a scalability wall for this particular set of data. It's a fairly high wall, as long as the data fits in memory--when not I/O-bound, Mongo can handle quite a lot of requests--but it's still placing all load for that data set on a single shard, which more robust designs always want to avoid, both for scalability and fault-isolation.
An improvement is to shard the separate collection on the unique field. This means that you can't change the value in-place; each time an email address changes, you have to create a new document with the record and delete the old one. That creates other challenges for reliability--you end up needing a two-phase commit mechanism to safely apply the change, which is a lot more work. However, it avoids those issues.
That's what I ended up doing. In terms of costs, a lookup hits one shard, and a modification hits up to three shards (the shard the old record resides on, the shard for the new record, and whichever shard the temporary transaction record is stored on), so changes are a bit latent but highly scalable.
I do wish Mongo would do this for me; it seems like a very common requirement, and doing it manually is error-prone and quite a lot of work. It's no easier for Mongo to do it, but at least then it'd be done just once, in a standard manner, and it'd receive more testing than isolated implementations. It's also a useful goal for all Mongo features to work with sharding; this would remove (or at least relax) the restrictions with sharding and unique indexes.