Faceted Search: 'Refine your Search'
joshheyse opened this issue · 3 comments
Full Disclosure: This is my first PostGraphile (and graphql) app. I am definitely still learning.
I am trying to implement a search page with similar features to CDWs "Refine your Search" where the user can select 0 or more values from an attribute type, if no values are selected the attribute type filter is ignored.
Some SQL sudo code would be:
SELECT title, brand, processor, price FROM computers WHERE (
(isNil($selectedBrands) OR brand IN $selectedBrands) AND
(isNil($selectedProcessors) OR processor IN $selectedProcessors)
)
I tried to use query variables as the LHS for a condition, but couldn't seem to get that to work.
Is this possible to do with the plugin connection filter? Do you have any recommendations on this type of query?
@joshheyse you should have no problem handling this, just use the and
field in the filter expression and add as many conditions as you want
If you set connectionFilterAllowNullInput: true
via graphileBuildOptions
, it will ignore any null
properties in the filter input object. Here's a full example:
drop schema if exists app_public cascade;
create schema app_public;
create table app_public.computer (
id integer primary key,
title text,
brand text,
processor text,
price numeric
);
insert into app_public.computer (id, title, brand, processor, price) values
(1, 'Acer Chromebase', 'Acer', 'Core i3', 799.00),
(2, 'Apple iMac', 'Apple', 'Core i5', 1499.00),
(3, 'ASUS Vivo', 'ASUS', 'Core i5', 999.00);
const express = require("express");
const { postgraphile } = require("postgraphile");
const ConnectionFilterPlugin = require("postgraphile-plugin-connection-filter");
const app = express();
app.use(
postgraphile("postgres://localhost:5432/issue_122", "app_public", {
appendPlugins: [ConnectionFilterPlugin],
graphiql: true,
graphileBuildOptions: {
connectionFilterAllowNullInput: true, // default: false
},
})
);
app.listen(5000);
query Computers($brands: [String!], $processors: [String!]) {
allComputers(filter: {
brand: { in: $brands }
processor: { in: $processors }
}) {
nodes {
id
title
brand
processor
price
}
}
}
// variables
{
"brands": ["Apple", "Acer"],
"processors": null
}
{
"data": {
"allComputers": {
"nodes": [
{
"id": 1,
"title": "Acer Chromebase",
"brand": "Acer",
"processor": "Core i3",
"price": "799.00"
},
{
"id": 2,
"title": "Apple iMac",
"brand": "Apple",
"processor": "Core i5",
"price": "1499.00"
}
]
}
}
}
There are some caveats with this approach; see https://github.com/graphile-contrib/postgraphile-plugin-connection-filter#handling-null-and-empty-objects for more information.
[semi-automated message] I'm going to close this issue due to lack of activity, but please feel free to continue the conversation below. 🙂