I'm trying to set up a disjunctive facet to provide options for an "OR" filter rule. As in, when I have multiple values in the facet group selected, it returns documents that match one, OR the other.
But out of the box, when I am using this recommended onChange handler:
onChange={() => onChange(value, !checked)}
It forces only one selection at a time. I was able to figure out how to make it allow multiple selections, however, when I do have multiple selections, I get zero results. I assume that despite being a disjunctive facet, it is using an AND condition for the filters.
Now I am questioning my assumption that this is even possible. Is what I am describing here the intended behavior for a disjunctive facet? Do they only force one selection, and prevent multiple selections?
Hi @John_Brandenburg, I'm a little unclear on what you're working with. Are you using Search UI? If so, you should be following this documentation on implementing disjunctive facets. If not, can you give us a little more info on what you're trying to accomplish, using what technology?
I am using the Search UI. I was trying to set up a facet that allowed multiple selections, but it was only allowing one filter at a time, despite being tagged as disjunctive. So the reason for my post was to clarify whether this is the expected behavior, or if I have screwed something up, which is a good possibility, as I had implemented a custom facet to handle some other use cases.
However, by requirements have actually changed since posting this, and I no longer need to set up this facet. But for posterity, here was the code for my custom facet:
import React from "react";
import { appendClassName, getFilterValueID } from "./helpers";
import type { FieldValue } from "@elastic/search-ui";
/**
* Use this function to override facet value labels.
*/
function getFilterValueDisplay(filterValue) {
let label = filterValue;
if (filterValue === "page") {
label = "Page";
}
else if (filterValue === "post") {
label = "Post";
}
...truncated
return label;
}
const CustomFacet = ({
className,
label,
onMoreClick,
onChange,
options,
showMore,
showSearch,
onSearch,
searchPlaceholder,
}) => (
<fieldset className={appendClassName("sui-facet", className)}>
<legend className="sui-facet__title">{label}</legend>
{showSearch && (
<div className="sui-facet-search">
<input
className="sui-facet-search__text-input"
type="search"
placeholder={searchPlaceholder || "Search"}
onChange={(e) => {
console.log('onchange');
console.log(e);
onSearch(e.target.value);
}}
/>
</div>
)}
<div className="sui-multi-checkbox-facet">
{options.length < 1 && <div>No matching options</div>}
{options.map((option) => {
const isBanned = function (filterValue) {
const banList = ["slideshow", "webform", "event", "publications"];
for (var i = 0; i < banList.length; i++) {
if (banList[i] == filterValue) return true;
}
};
if (isBanned(option.value)) {
console.log('banned');
return;
}
const checked = option.selected;
const value = option.value;
return (
<label
key={`${getFilterValueID(option.value)}`}
htmlFor={`example_facet_${label}${getFilterValueID(option.value)}`}
className="sui-multi-checkbox-facet__option-label">
<div className="sui-multi-checkbox-facet__option-input-wrapper">
<input
data-transaction-name={`facet - ${label}`}
id={`example_facet_${label}${getFilterValueID(option.value)}`}
type="checkbox"
className="sui-multi-checkbox-facet__checkbox"
checked={checked}
onChange={() => onChange(value, !checked)} // Update the callback here
/>
<span className="sui-multi-checkbox-facet__input-text">
{getFilterValueDisplay(option.value)}
</span>
</div>
<span className="sui-multi-checkbox-facet__option-count">
{option.count.toLocaleString('en')}
</span>
</label>
);
})}
</div>
{showMore && (
<button
type="button"
className="sui-facet-view-more"
onClick={onMoreClick}
aria-label="Show more options"
>
+ More
</button>
)}
</fieldset>
);
export default CustomFacet;
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.