> ## Documentation Index
> Fetch the complete documentation index at: https://doc.lucidworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Field Facet

> Query pipeline stage configuration specifications

export const schema = {
  "type": "object",
  "title": "Facets",
  "description": "Configure range or field facets. Facets indicate categories and aggregations of results according to values in the configured fields",
  "properties": {
    "skip": {
      "type": "boolean",
      "title": "Skip This Stage",
      "description": "Set to true to skip this stage.",
      "default": false,
      "hints": ["advanced"]
    },
    "label": {
      "type": "string",
      "title": "Label",
      "description": "A unique label for this stage.",
      "hints": ["advanced"],
      "maxLength": 255
    },
    "condition": {
      "type": "string",
      "title": "Condition",
      "description": "Define a conditional script that must result in true or false. This can be used to determine if the stage should process or not.",
      "hints": ["code", "code/javascript", "advanced"]
    },
    "legacy": {
      "type": "boolean",
      "title": "Legacy",
      "description": "True if this stage only supports legacy mode",
      "hints": ["readonly", "hidden"]
    },
    "fieldFacets": {
      "type": "array",
      "title": "Facet Fields",
      "items": {
        "type": "object",
        "required": ["field"],
        "properties": {
          "field": {
            "type": "string",
            "title": "Field",
            "description": "The field whose values you want to facet on."
          },
          "prefix": {
            "type": "string",
            "title": "Prefix",
            "description": "Prefix of terms to facet on."
          },
          "sort": {
            "type": "string",
            "title": "Sort",
            "description": "Ordering of the faceting results.",
            "enum": ["count", "index"]
          },
          "limit": {
            "type": "integer",
            "title": "Limit",
            "description": "Maximum number of facets to return."
          },
          "offset": {
            "type": "integer",
            "title": "Offset",
            "description": "Offset into list of resulting facets."
          },
          "minCount": {
            "type": "integer",
            "title": "Minimum Count",
            "description": "Lower threshold of term counts to be included.",
            "default": 1
          },
          "missing": {
            "type": "boolean",
            "title": "Count Missing",
            "description": "Optionally include a 'missing' facet bucket for documents without the selected field.",
            "default": false
          },
          "method": {
            "type": "string",
            "title": "Method",
            "enum": ["per_term", "per_doc", "per_segment", "doc_values", "un_inverted_field", "doc_values_hash", "enum"]
          },
          "enumCacheMinDf": {
            "type": "integer",
            "title": "Enum Cache Minimum DF",
            "description": "This property is only supported for non DSL requests."
          },
          "ensuredValues": {
            "type": "array",
            "title": "Ensured Facet Values",
            "description": "Field values to include statistics for, even if they don't fall within the natural top-\"limit\"values for the facet.  Only supported on DSL requests.",
            "items": {
              "type": "string"
            }
          },
          "boostValues": {
            "type": "array",
            "title": "Boost Values",
            "description": "Field values to boost in the facet results. (Requires Modify Response stage)",
            "items": {
              "type": "string"
            }
          },
          "buryValues": {
            "type": "array",
            "title": "Bury Values",
            "description": "Field values to bury in the facet results. (Requires Modify Response stage)",
            "items": {
              "type": "string"
            }
          },
          "suppressValues": {
            "type": "array",
            "title": "Suppress Values",
            "description": "Field values to suppress from the facet results. (Requires Modify Response stage)",
            "items": {
              "type": "string"
            }
          },
          "threads": {
            "type": "integer",
            "title": "NO LONGER USED.",
            "hints": ["hidden"],
            "minimum": 0,
            "exclusiveMinimum": false
          },
          "order": {
            "type": "integer",
            "title": "Display Order",
            "description": "Order in which this facet appears in the response. Lower values appear first. If not specified, facet appears after all ordered facets.",
            "minimum": 0,
            "exclusiveMinimum": false
          }
        }
      }
    },
    "threads": {
      "type": "integer",
      "title": "Field facet threads (Advanced)",
      "description": "Specifies how many threads the search engine will use while loading the underlying fields used in faceting. Recommended that this is kept at 0 or blank, which means the data is loaded in the thread already running the query.  Only supported on non DSL requests."
    },
    "rangeFacets": {
      "type": "array",
      "title": "Range Facet Fields",
      "items": {
        "type": "object",
        "required": ["field", "start", "end", "gap"],
        "properties": {
          "field": {
            "type": "string",
            "title": "Field",
            "description": "The field whose values you want to range facet on."
          },
          "start": {
            "type": "string",
            "title": "Start",
            "description": "Specifies the lower bound of the range."
          },
          "end": {
            "type": "string",
            "title": "End",
            "description": "Specifies the upper bound of the range."
          },
          "gap": {
            "type": "string",
            "title": "Gap",
            "description": "The span of each range expressed as a value to be added to the lower bound."
          },
          "hardEnd": {
            "type": "boolean",
            "title": "Hard End",
            "description": "Specifies how to handle cases where the gap does not divide evenly between start and end."
          },
          "minCount": {
            "type": "integer",
            "title": "Minimum Count",
            "description": "Lower threshold of term counts to be included.",
            "default": 1
          },
          "method": {
            "type": "string",
            "title": "Method",
            "enum": ["filter", "doc_values"]
          },
          "include": {
            "type": "array",
            "title": "Include",
            "description": "Specifies how bounds are processed.",
            "items": {
              "type": "string",
              "enum": ["lower", "upper", "outer", "edge", "all"]
            }
          },
          "other": {
            "type": "array",
            "title": "Other",
            "description": "Specifies additional counts.",
            "items": {
              "type": "string",
              "enum": ["before", "after", "between", "non", "all"]
            }
          },
          "boostValues": {
            "type": "array",
            "title": "Boost Values",
            "description": "Field values to boost in the facet results.",
            "items": {
              "type": "string"
            }
          },
          "buryValues": {
            "type": "array",
            "title": "Bury Values",
            "description": "Field values to bury in the facet results.",
            "items": {
              "type": "string"
            }
          },
          "suppressValues": {
            "type": "array",
            "title": "Suppress Values",
            "description": "Field values to suppress from the facet results.",
            "items": {
              "type": "string"
            }
          },
          "order": {
            "type": "integer",
            "title": "Display Order",
            "description": "Order in which this facet appears in the response. Lower values appear first. If not specified, facet appears after all ordered facets.",
            "minimum": 0,
            "exclusiveMinimum": false
          }
        }
      }
    }
  },
  "category": "Set Up",
  "categoryPriority": 8,
  "unsafe": false
};

export const SchemaParamFields = ({schema}) => {
  const sanitize = str => {
    if (typeof str !== "string") return str;
    return str.replace(/^"(.*)"$/s, "$1").replace(/\\/g, "").replace(/"/g, "'");
  };
  const formatDescription = str => {
    const s = sanitize(str);
    return (/[.!?]\)*$/).test(s) ? s : `${s}.`;
  };
  const {description, properties = {}, required: requiredProps = []} = schema;
  const visibleProps = useMemo(() => Object.entries(properties).filter(([, prop]) => !prop.hints?.includes("hidden")), [properties]);
  return <div>
      {description && <p>{formatDescription(description)}</p>}

      {visibleProps.map(([name, prop]) => {
    const isRequired = requiredProps.includes(name);
    const hasDefault = prop.default !== undefined;
    const rawDefault = prop.default;
    const isComplexDefault = hasDefault && (typeof rawDefault === "object" || typeof rawDefault === "string" && (rawDefault.length > 20 || rawDefault.includes('"')));
    const fieldProps = {
      key: name,
      body: prop.title || name,
      type: prop.type,
      ...prop.title && ({
        post: [<><span className="text-stone-400 dark:text-stone-500">API property: </span>{name}</>]
      }),
      ...isRequired && ({
        required: true
      }),
      ...!isComplexDefault && hasDefault ? {
        default: sanitize(String(rawDefault))
      } : {}
    };
    const isObject = prop.type === "object" && prop.properties;
    const isArrayOfObjects = prop.type === "array" && prop.items?.type === "object" && prop.items.properties;
    return <ParamField {...fieldProps}>
            {prop.description && <p>{formatDescription(prop.description)}</p>}

            {isComplexDefault && <div className="flex">
                <p>
                  <strong>Default:</strong>
                </p>
                <pre className="!my-0">
                  <code>
                    {JSON.stringify(rawDefault, null, 2)}
                  </code>
                </pre>
              </div>}

            {isArrayOfObjects && <div className="flex">
              <p>
                <strong>Object attributes:</strong>
              </p>
              <pre className="!my-0">
                <code>
                  {'{\n'}
                  {Object.entries(prop.items.properties).map(([iname, iprop]) => <>
                      {`  ${iname}`}
                      {prop.items?.required?.includes(iname) && <span style={{
      color: 'red'
    }}> required</span>}
                      {`: {\n    display name: ${sanitize(iprop.title || '')}\n    type: ${iprop.type}\n  }\n`}
                    </>)}
                  {'}'}
                </code>
              </pre>
              </div>}

            {isObject && <Expandable title="properties">
                <SchemaParamFields schema={{
      properties: prop.properties,
      required: prop.required
    }} />
              </Expandable>}
          </ParamField>;
  })}
    </div>;
};

export const LwTemplate = ({title = "Key questions to get you started", icon = "sparkles", cta = "Powered by Agent Studio", linkHref = "https://lucidworks.com/demo/?utm_source=docs&utm_medium=referral&utm_campaign=docs_cta_ai"}) => {
  const [isLoaded, setIsLoaded] = useState(false);
  useEffect(() => {
    const timer = setTimeout(() => {
      setIsLoaded(true);
    }, 500);
    return () => clearTimeout(timer);
  }, []);
  return <div className="lw-template-container">
      <Card title={title} icon={icon}>
        {isLoaded && <span dangerouslySetInnerHTML={{
    __html: `<lw-template id="a029c1a9-28be-427e-b0e1-5d918920246a"></lw-template
            >`
  }} />}
        <Link href={linkHref} className="agent-studio-link text-left text-gray-600 gap-2 dark:text-gray-400 text-sm font-medium flex flex-row items-center hover:text-primary dark:hover:text-primary-light group-hover:text-primary group-hover:dark:text-primary-light">Powered by Lucidworks Agent Studio</Link>
      </Card>
    </div>;
};

[localhost link]: http://localhost:3000/docs/lucidworks-search/09-developer-documentation/config-specs/query-pipeline-stages/field-facet

[mintlify link]: https://doc.lucidworks.com/docs/lucidworks-search/09-developer-documentation/config-specs/query-pipeline-stages/field-facet

[old doc.lw link]: https://doc.lucidworks.com/managed-fusion/5.9/jqbnij

The Field Facet query pipeline stage is used to add a
[Solr Field Facet query](https://cwiki.apache.org/confluence/display/solr/Faceting#Faceting-Field-ValueFacetingParameters)
to the search query pipeline.

A field facet query computes the top values for a field and returns the list of those values along with a count of the subset
of documents in the search results which match that term.
Field faceting works best over fields which contain a single label or set of labels from a finite, controlled lexicon
such as product category.
Facet field parameters can be tuned for performance, see:
[Facet Field Configuration](https://cwiki.apache.org/confluence/display/solr/Faceting#Faceting-Field-ValueFacetingParameters).

It is possible to specify more than one field facets.
For each field facet you must specify the field name plus the following additional parameters:

* **Limit.** The maximum number of terms to be returned. Default 100.
* **Offset.** The number of top facet values to skip in the response. Default 0.
* **Sort.** The order in which to list facet values: `count` ordering is by documents per term, descending, and `index` ordering is sorted on term values themselves.
* **Missing.** The number of documents in the results set which have no value for the facet field.
* **Choice of facet method (advanced).** Specify Solr algorithm used to calculate facet counts.
  (See [Facet Method Configuration](https://cwiki.apache.org/confluence/display/solr/Faceting#Faceting-Thefacet.methodParameter) for details)\
  One of:

  * `enum`. Small number of distinct categories.
  * `fc` ("field cache"). Many different values in the field, each document has low number of values, multi-valued field.
  * `fcs` ("single value string fields"). Good for rapidly changing indexes.

For further details see: [Solr Faceting Overview](https://lucene.apache.org/solr/guide/faceting.html).

<LwTemplate />

## Configuration

<SchemaParamFields schema={schema} />
