An alternative to querying with multiple JOIN over the same table?
You could try to aggregate the features into a JSON value, then searching for a combination of multiple features is quite easy:

select h.*, hf.features
from houses
  join (
    select house_id, jsonb_object_agg(feature_name, feature_value) as features
    from house_features
    group by house_id
  ) hf on hf.house_pkid = h.pkid 
where hf.features @&gt; '{"rooftype": "flat", "has_basement", "true", "wallcolors": "white"}';


Performance can be improved by adding a WHERE clause to the sub-select which repeats the feature names, e.g:

where feature_name in ('rooftype', 'has_basement', 'wallcolors')


or even 

where (feature_name, feature_value) in (('rooftype', 'flat') ('has_basement', 'true'), ('wallcolors', 'white'))


The outer condition is still necessary, because the inner where will include houses that don't have all the features. 

This also has the advantage (in my eyes) that you only get one row with all the features, rather then one row for each feature. 



Unless you remove, add and change features for a house very frequently, storing them as a single JSONB column on the house table  (features) and getting rid of the house_features table, might be an alternative. In that case you could create an index on the column to speed up the search.