Triplet loss.
https://pytorch.org/docs/stable/generated/torch.nn.TripletMa...
Triplet loss takes an anchor, positive, and negative. In this case the anchor is your query, the positive is a similar doc, and the negative is a dissimilar doc. When you train, backpropagate the loss to both the doc and the query encoder.