> ## 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.

# Update Related Document

> Index pipeline stage configuration specifications

export const schema = {
  "type": "object",
  "title": "Update Related Document",
  "description": "Performs an atomic update on an existing Solr document that is related to the document currently being indexed. Use a real-time get query or a standard Solr query to locate the related document, then specify the fields to update. For example, use this stage to set a `has_clicks` flag on a request signal when the first click signal is indexed.",
  "required": ["fieldsToUpdate"],
  "properties": {
    "skip": {
      "type": "boolean",
      "title": "Skip This Stage",
      "description": "Controls whether this stage executes during pipeline processing at runtime. When set to `true`, the stage is completely bypassed and documents pass through unchanged to the next stage. Useful for A/B testing, gradual rollouts, or temporarily disabling a stage without removing it from the pipeline.",
      "default": false,
      "hints": ["advanced"]
    },
    "label": {
      "type": "string",
      "title": "Label",
      "description": "Human-readable identifier displayed in the Fusion Admin UI, monitoring dashboards, and log messages. Use descriptive labels like `Parse Product PDFs` to aid debugging and team collaboration. Labels appear in performance metrics and error reports, making it easier to identify which stage failed.",
      "hints": ["advanced"],
      "maxLength": 255
    },
    "condition": {
      "type": "string",
      "title": "Condition",
      "description": "JavaScript expression evaluated at runtime on each document to conditionally execute this stage. The expression must return `true` to execute or `false` to skip. Access document fields using `doc.getFieldValue('fieldName')` and request parameters via `request.getFirstParam('paramName')`. For example, `doc.getFieldValue('type') === 'premium'` executes this stage only for premium content.",
      "hints": ["code", "code/javascript", "advanced"]
    },
    "realTimeGetQuery": {
      "type": "string",
      "title": "Find Related Document (RTG)",
      "description": "Specifies a Solr real-time get query to locate the related document to update. The query must uniquely identify one document. If multiple documents match, only the first is used. Prefer real-time get over a standard lookup query when the document may not yet be visible in search results.",
      "hints": ["lengthy"]
    },
    "lookupQuery": {
      "type": "string",
      "title": "Find Related Document (Query)",
      "description": "Specifies a Solr search query to find the related document to update. Only the first document in the result set is used for the update. Use the `lookupSort` field to control which document is selected when multiple results are returned.",
      "hints": ["lengthy"]
    },
    "lookupSort": {
      "type": "string",
      "title": "Sort Order",
      "description": "Specifies the sort order applied to the lookup query results to determine which document is selected for the atomic update. For example, `score desc` selects the highest-scoring match. This field is ignored when using a real-time get query."
    },
    "applyLookupCriteria": {
      "type": "string",
      "title": "Only lookup related docs when",
      "description": "Specifies an optional expression that controls whether this stage attempts to find and update a related document for each incoming document. When the expression evaluates to `false`, the lookup and update are skipped entirely. Use this to avoid unnecessary Solr queries for documents that have no related document to update."
    },
    "fieldsToUpdate": {
      "type": "array",
      "title": "Fields to Update",
      "description": "Defines the list of key-value pairs that set field values on the related Solr document via an atomic update. Each entry specifies a field name and a value, which can be a constant or a reference to a field on the incoming pipeline document. All specified fields are written to the related document atomically.",
      "items": {
        "type": "object",
        "required": ["key"],
        "properties": {
          "key": {
            "type": "string",
            "title": "Parameter Name"
          },
          "value": {
            "type": "string",
            "title": "Parameter Value"
          }
        }
      }
    },
    "collection": {
      "type": "string",
      "title": "Collection",
      "description": "Specifies the name of the Solr collection that contains the related document to update. The collection must exist in the Fusion Solr cluster and be accessible from the pipeline. When empty, the pipeline's default collection is used.",
      "hints": ["advanced"]
    },
    "idField": {
      "type": "string",
      "title": "ID Field",
      "description": "Specifies the name of the ID field used to identify documents in the Solr collection during the real-time get query. This field uniquely identifies each document in the collection. Change this only when the target collection uses a non-standard ID field name.",
      "default": "id",
      "hints": ["advanced"]
    },
    "commitWithinOverride": {
      "type": "integer",
      "title": "Commit Within Override",
      "description": "Sets the number of milliseconds Solr waits before committing the atomic update to make it visible. When empty, the collection's default `commitWithin` setting is used. Use a lower value to make the update visible sooner at the cost of more frequent commit operations.",
      "hints": ["advanced"]
    },
    "secsToCacheRecentlyUpdatedDocs": {
      "type": "integer",
      "title": "Seconds to Cache Recent Updates",
      "description": "Sets the number of seconds recently updated related documents are cached to skip redundant lookups and updates for the same document. Keep this value under a few minutes to avoid missing legitimate updates that arrive within the cache window. Set to `-1` to disable caching entirely.",
      "hints": ["advanced"]
    }
  },
  "category": "Indexing",
  "categoryPriority": 5,
  "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 renderMd = str => {
    const s = sanitize(str);
    const text = (/[.!?]\)*$/).test(s) ? s : `${s}.`;
    return text.split(/(\*\*[^*]+\*\*|_[^_]+_|`[^`]+`)/g).map((part, i) => {
      if (part.startsWith("**")) return <strong key={i}>{part.slice(2, -2)}</strong>;
      if (part.startsWith("_")) return <em key={i}>{part.slice(1, -1)}</em>;
      if (part.startsWith("`")) return <code key={i}>{part.slice(1, -1)}</code>;
      return part;
    });
  };
  const {description, properties = {}, required: requiredProps = []} = schema;
  const visibleProps = useMemo(() => Object.entries(properties).filter(([, prop]) => !prop.hints?.includes("hidden")), [properties]);
  const renderProp = ([name, prop]) => {
    const isRequired = requiredProps.includes(name);
    const hasDefault = prop.default !== undefined;
    const rawDefault = prop.default;
    const hints = prop.hints || [];
    const isComplexDefault = hasDefault && (typeof rawDefault === "object" || typeof rawDefault === "string" && (rawDefault.length > 20 || rawDefault.includes('"')));
    const postBadges = [];
    if (prop.title) {
      postBadges.push(<><span className="text-stone-400 dark:text-stone-500">API property: </span>{name}</>);
    }
    const constraints = [];
    if (prop.minimum !== undefined && prop.maximum !== undefined) {
      constraints.push(`Range: ${prop.minimum} – ${prop.maximum}`);
    } else if (prop.minimum !== undefined) {
      constraints.push(`Min: ${prop.minimum}`);
    } else if (prop.maximum !== undefined) {
      constraints.push(`Max: ${prop.maximum}`);
    }
    if (prop.minLength !== undefined && prop.maxLength !== undefined) {
      constraints.push(`Length: ${prop.minLength} – ${prop.maxLength}`);
    } else if (prop.minLength !== undefined) {
      constraints.push(`Min length: ${prop.minLength}`);
    } else if (prop.maxLength !== undefined) {
      constraints.push(`Max length: ${prop.maxLength}`);
    }
    const fieldProps = {
      key: name,
      body: prop.title || name,
      type: prop.type,
      ...postBadges.length > 0 && ({
        post: postBadges
      }),
      ...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>{renderMd(prop.description)}</p>}

        {prop.enum && <p>
            Allowed values: 
            {prop.enum.map((v, i) => <>{i > 0 && ", "}<code key={i}>{String(v)}</code></>)}
          </p>}

        {constraints.length > 0 && <p className="text-stone-500 dark:text-stone-400 text-sm">
            {constraints.join(" · ")}
          </p>}

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

        {isArrayOfObjects && <Expandable title="item properties">
            <SchemaParamFields schema={{
      properties: prop.items.properties,
      required: prop.items.required
    }} />
          </Expandable>}

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

      {visibleProps.map(renderProp)}
    </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/index-pipeline-stages/update-related-document

[mintlify link]: https://doc.lucidworks.com/docs/lucidworks-search/09-developer-documentation/config-specs/index-pipeline-stages/update-related-document

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

This index pipeline stage performs a Solr atomic update on an existing document using data pulled from the current document being processed by the pipeline.

<LwTemplate />

## Configuration

<Tip>
  When entering configuration values in the UI, use *unescaped* characters, such as `\t` for the tab character. When entering configuration values in the API, use *escaped* characters, such as `\\t` for the tab character.
</Tip>

In the **Find Related Document (RTG)** field, enter the Solr query to look up the related document to update using a real-time `GET` request. The query needs to uniquely identify the document to be updated in an `id=<value>` format. For more information, see the [Solr’s RealTime Get documentation](https://solr.apache.org/guide/solr/latest/configuration-guide/realtime-get.html)..

In the **Find Related Document (Query)** field, enter the Solr query to look up the related document to update. Only the first document returned in the results is used. The query can contain any `field:<value>` and needs to uniquely identify the document to be updated. The `id:<value>` field is one example.

<SchemaParamFields schema={schema} />
