By default, Lucene sorts based on TEXT-RELEVANCE only. There are quite a few factors that contribute to the relevance score.
It is possible that tf-idf values and length normalization might have affected your scores resulting in having "a b" / "b c" documents show up at top ranked results than the documents containing "a b c".
The way you can overcome above is that To boost the relevance score based on number of matching query terms. You may follow the below steps.
1) Write a customized Similarity class extending from DefaultSimilarity. If you are wondering what's Similarity, it is the class used by Lucene that contains all the formulas of scoring factors that contribute to the score.
Tutorial : Lucene Scoring
2) Override DefaultSimilarity.coord()
coord() explanation in the Lucene documentation.
coord(q,d) is a score factor based on how many of the query terms are found in the specified document. Typically, a document that contains more of the query's terms will receive a higher score than another document with fewer query terms. This is a search time factor computed in coord(q,d) by the Similarity in effect at search time.
3) The default implementation of coord is overlap/maxoverlap. You may experiment with different formulas such that the documents containing more query words show up in the top results. The following formulas might be good starting points.
1) coord return value = Math.sqrt(overlap/maxoverlap)
2) coord return value = overlap;
4) You do NOT have to override other methods since the DefaultSimilarity has default implementations for all scoring factors. Just touch the one you want to experiment with, which is coord() in your case. If you extend from Similarity, you've to provide all the implementations.
5) Similarity can be passed to the IndexSearcher using IndexSearcher.setSimilarity()