Lucene is not a binary matching tool, it doesn't think of things as right or wrong, matched or not. Things are allowed to match to a degree with optional pieces of criteria. This is where should comes in - these are optional extras that are nice-to-haves that go along with the stricter must-have and must-not-have type bool clauses. This is what you have in your example with the should clause appearing alongside the strict filter clause.
When you have no strict clauses in a bool expression the should clause is promoted from being optional - at least one of the clauses it contains must match. So to implement strict OR boolean logic you need a bool expression with a should array of the choices and nothing else.