Do multiple docker filter options perform a local AND or OR operation?

I am trying to perform a prune operation with multiple filters. This is covered in the docs here:

The filtering flag (–filter) format is of “key=value”. If there is more than one filter, then pass multiple flags (e.g., --filter “foo=bar” --filter “bif=baz”)

The docs fail to mention if using multiple filters like this combining them using a logical AND or OR operation.

I would like it to be an AND operation so that I can do something like this:

docker image prune --all --force --filter="label=com.company.product=myproduct" \
    --filter="label!=com.company.project=proj2"

and a Dockerfile with the following labels would not be pruned:

LABEL com.company.product="myproduct" com.company.project="proj2"

Is this possible?

After doing some testing it appears to be an AND operation, so something like this should work:

docker image prune --all --force --filter="label=com.company.product=myproduct" \
    --filter="label=com.company.project=proj2"

The use case described above is definitely ANDed and indeed in pretty much all cases where multiple filters are used are ANDed except when multiple negated label filters which are instead ORed together. This is undocumented and I believe it should not work this way so I have submitted an issue about this but for those wanting this functionality now:

bash -c '{ docker ps -aq --filter "status=exited" && docker ps -aq --filter "label=foo" && docker ps -aq --filter "label=bar"; }' | sort | uniq -u | xargs --no-run-if-empty docker rm

Add or remove && docker ps -aq --filter "label=<label exclude from pruning>" in the command to add or remove negated label filters. Other non-negated filters should be added to the first instance of docker ps (eg docker ps -aq --filter "status=exited" --filter "until=24h"). bash -c is only necessary for users of shells which don’t support the bash specific syntax used above (like fish).