View this page in the latest version of Appian. Configure Smart Search Share Share via LinkedIn Reddit Email Copy Link Print On This Page The capabilities described on this page are included in Appian's advanced and premium capability tiers. Usage limits may apply. Tip: Smart search is available as a preview. Preview features are fully supported; however, they do not reflect the full functionality or performance of the feature yet. Appian will respond to support issues and will maintain backwards compatibility in future updates. Overview Smart search transforms how you find records in a synced record type by using AI-powered semantic search to uncover connections, detect patterns, and surface related records across thousands of records. Smart search understands your intent and returns better results because it's not just using keywords. After you enable smart search on your synced record type, you can add smart search to any query in your data fabric by using the search operator in the a!queryFilter function combined with the a!queryRecordType function. This includes queries used in read-only grids. This allows you to apply smart search directly to your record type and start finding the information that matters most. Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close What is smart search? Smart search is an AI-powered way to find information in a record type. Instead of just looking for exact matches to the words you type, it understands the meaning behind your search. This means it understands what you're really looking for, not just the words you used. For example, if you search for "electricity outage," smart search might also show results that mention "power failure" or "electricity is down." When combined with filters, smart search makes it easier to uncover connections, detect patterns, and find the information that truly matters to you. Here's what makes smart search so powerful: Uncovers hidden connections: Smart search identifies records even when different terminology is used; for example, "overdue bill" or "pending payment." Investigate patterns: Smart search can help you recognize trends across records, such as similar cases logged at the same time by different users. Searches across text: You can use smart search on text and document type fields. For example, smart search helps you locate the exact records you need, whether the information is in detailed titles or extended descriptions. Find what you need faster: Smart search uses similarity scores to automatically prioritize your search results. Higher scores show closer matches, helping you quickly locate the most relevant information. For best results, sort by similarity score in descending order to surface the best matches first. Accelerate your workflows: Smart search highlights the most closely related records, making it easier to detect duplicates, related cases, and recurring patterns. These insights help you act faster, whether you are merging duplicate entries or resolving high-priority issues with the help of AI-driven smart search and AI skills. Integrate into data-driven processes: Use additional AI features to make smart search even more powerful. Using one or two records as an example of what information you're looking for, you can use generative AI skills to generate the most specific search strings to help uncover additional relevant records. When to use smart search Smart search is most useful when your users may not know the exact value they are looking for, such as finding related cases or similar requests. Review the following use cases to see how smart search solves real problems in everyday processes, where it works best, and how it adds value to your application. Find records faster in grid components Business users often work with large data sets in read-only-grid components(a!gridField`). Without a search feature, you need to scroll or apply manual filters to find what they need. Smart search simplifies this by letting your users enter search terms or sentences. Then smart search finds related sentences with similar meaning and quickly locates the right records, even when your users search with incomplete or imprecise search terms. See the Read-Only Grid Component page for more details. Identify and act on similar cases Smart search can surface similar records to support faster decision-making. For example, when you search for a case, Appian can automatically suggest other cases with similar names and descriptions. If those cases describe the same issue, like multiple reports of a power outage, you can choose to merge them into a single case. This reduces duplication and keeps your data clean. This approach combines AI-powered suggestions with your judgment, improving efficiency without removing control. Example Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close Automate decision making Smart search can work behind the scenes in a process model to support automated decision-making. By combining smart search with AI skills, you can deliver next-step suggestions without user input. This approach helps you automate common decisions and deliver consistent, informed actions across similar cases. For example, when a new case is created, Appian can use smart search to find similar cases based on the case name and description. Appian can then query the notes from resolved cases and send them to a prompt builder AI skill, along with custom instructions. The AI skill uses that context to generate recommended next steps for the current case. Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close Key concepts To get the most out of smart search, it's helpful to understand a few key concepts. Keyword search and smart search Keyword search and smart search work differently to find matches in your data. A keyword search looks for each word you enter and finds matches in any text, number (integer), user, or group field inside a read-only grid. For example, the search phrase "order proceed" matches: "press refresh in order to proceed with my development." You'll see results that include any or all of the words you type. Keyword matches are always available when using a read-only grid. By default, the similarityScoreThreshold is set to 1, so only search results that are a keyword match are returned. Smart search is limited to text and document fields inside the a!queryRecordType() parameter or a!gridColumn. For more information about adding smart search to your read-only grids and queries, see the Add smart search to any query to your data fabric topic. Similarity score A similarity score is a number between 0 and 1 that indicates how closely a field matches your search. In smart search, every search result gets a similarity score, with higher scores meaning the result is more relevant to what you're looking for. While a similarity score of 1 always represents an exact match, the significance of any other score is relative. What qualifies as a strong or weak match depends entirely on your data and how you're using smart search. The list below provides a general starting point for interpreting similarity scores. Note: You will need to test and verify similarity scores with your own data to determine which ranges are most meaningful for your data and use case. The following list should only be used as a starting point, you'll likely need to adjust these numbers. Exact Match: 1 Strong Match: 0.0058 or greater Moderate Match: Between 0.0029 and 0.0057 Fair Match: Between 0.0022 and 0.0028 Weak Match: 0.0021 or below No Match: null Example 1: Case record type For example, let's say you have smart search enabled on the description field in the Case record type. This field contains narrative, sentence-based text about a support case. When you search for customer reporting an incorrect invoice charge in a case grid, you may see the following results. Based on the returned results, you determine that a score starting at 0.0058 is a strong match for this field since it identifies direct complaints. A score of 0.0021 or less is considered a weak match since it found related but incorrect topics (like requesting a copy instead of reporting an error). Id Source Content Similarity Score Match Quality 3 "Customer is disputing a charge on their bill." 0.0059 Strong 36 "…a fee was added to the account in error…" 0.0058 Strong 9 "Customer is requesting a copy of their invoice." 0.0021 Weak Example 2: Order record type Now let's say you have smart search enabled on the description field in the Order record type. This field contains less structured text about customer orders, often mixed with product features and notes. When you search for raincoats in black in an order grid, you may see the following results. In the returned results, you notice that more relevant results are returned at a lower similarity score. As such, for the description field in the Order record type, you decide that a strong match actually starts at 0.0023. Id Source Content Similarity Score Match Quality 30 "Item: Waterproof Trench Coat, Color: Black" 0.0028 Strong 82 "Product: Waterproof Jacket, Size: S, Color: Charcoal" 0.0023 Strong 6 "Notes: Customer also bought a black umbrella." 0.0016 Weak Using similarity scores You can use the similarity score to filter or sort results, making it easier to focus on the information that matters most. To reference the similarity score, as well as other search result data, you can use the searchResults property of the record type. As a best practice, you should sort and filter data by the primary similarity score since you're likely searching across multiple fields. To reference the primary similarity score, use the following reference: recordType!<Record Type Name>.searchResults.allSearchFields.similarityScore You can use similarity scores in your application in a couple of ways: In a read-only grid: You can sort and filter a grid by similarity score. Add a column in the read-only grid to display the quality of the similarity score. For example, if you determine that a strong score is 0.0045, you could display "Strong" as a value in that column. You should not display the numerical similarity score to application users, since understanding their meaning is data and case specific. Set a similarity score threshold to filter out less relevant search results. By default, the threshold is 1 (only keyword matches), but lowering it will return both keyword and smart search matches with scores at or above the threshold. In an a!queryRecordType() expression: You can sort and filter a query by similarity score. For example, the following expression searches the same value on the title and description fields, and sorts the results based on the primary similarity score. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 a!queryRecordType( recordType: recordType!SSTA Case, fields: { recordType!SSTA Case.fields.id, recordType!SSTA Case.fields.title, recordType!SSTA Case.fields.description, recordType!SSTA Case.searchResults.allSearchFields.similarityScore, }, /* Combine multiple search filters using an "OR" operator */ filters: a!queryLogicalExpression( operator: "OR", filters: { /* Search on the title field */ a!queryFilter( field: recordType!SSTA Case.fields.title, operator: "search", value: "software update", ), /* Search on the description field */ a!queryFilter( field: recordType!SSTA Case.fields.description, operator: "search", value: "software update", ) } ), pagingInfo: a!pagingInfo( startIndex: 1, batchSize: 100, sort: a!sortInfo( field: recordType!SSTA Case.searchResults.allSearchFields.similarityScore, ascending: false() ) ) ) Similarity Score Threshold parameter behavior In a read-only grid, the similarityScoreThreshold parameter controls how closely results must match the search term. This parameter is only available when the showSearchBox parameter is true, so it only applies when you're using the default search box in a grid. Using higher values in this parameter will set a stricter requirement, returning fewer and more relevant results. Lower values will return more results with a broader range of relevance. By default, this parameter is 1 to return only exact keyword matches. You can use both keyword search and smart search in the grid by lowering this value. See general guidelines for interpreting similarity scores to help pick a starting point for your threshold. Primary similarity score The primary similarity score represents the highest similarity score Appian finds from any searched field or section of content for a given record. To retrieve how and where the match occurred, use: searchResults.allSearchFields.similarityScore: This field provides the primary similarity score for a record when a smart search is performed across multiple fields. searchResults.allSearchFields.sourceContent: This field indicates the specific content that matched the search term and resulted in the highest similarity score for that record. searchResults.allSearchFields.sourceField: The field where the search term with the highest similarity score was found. Use this to access the contents of the matched field. For example, imagine you have a grid displaying case information where the fields title and description are enabled for smart search. When you enter a search term: If the title in the first row is a better semantic match than the description, allSearchFields.similarityScore and sourceContent will match searchResults.title.similarityScore and searchResults.title.sourceContent for that row. If, in the second row, the better match is found in the description field, then allSearchFields.similarityScore and sourceContent will match searchResults.description.similarityScore and searchResults.description.sourceContent for that row. How smart search indexes data Indexing is how smart search prepares your data so it can appear in search results. When you enable a field for smart search, Appian syncs the record type and indexes your smart search fields, organizing them for quick retrieval. Think of indexing like building a table of contents. Without it, smart search wouldn't know what data is available or where to find it. Each time your data changes—when records are added or updated—Appian re-indexes the content to keep search results accurate. Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close Keeping smart search data current Whenever a full sync or smart service sync occurs on the record type, those changes are automatically reflected in the smart search as well. To index data for smart search during a scheduled full sync, select Refresh smart search data. Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close Tip: When you update your data model, don't forget to revisit the Smart Search tab to ensure the fields you want to enable for smart search are selected. Source content The piece of text where the search term was found. This is useful if you want to send the matched search term and its surrounding text to an AI skill. sourceContent appears inside recordType!<<recordTypeName>>.searchResults You can also reference sourceContent through a field reference: recordType!<<record type name>>.searchResults.<<field name>>.sourceContent Passing search results to a process model When passing search results to a process model, ensure that the full context of the search is preserved. If you extract specific fields from the search results (e.g., searchResults.allSearchFields.similarityScore) before passing them to the process model, the associated search metadata may be lost. This can lead to issues where the process model cannot access the necessary search context, potentially causing errors downstream. To maintain the complete search context: Pass the entire record, including the searchResults, to the process model. Avoid indexing into specific search result fields before passing the data. In the process model, store the incoming data into a variable for the appropriate record type. By passing the full record, the process model retains access to all search-related metadata, such as similarity scores and source content, ensuring that any logic dependent on this information functions correctly. Considerations Keep these considerations in mind when enabling smart search to ensure optimal performance and compatibility with your data. Category Details Region availability This feature is available for environments in select regions. If your Appian environment isn't in a supported region, you can elect to send your data to a supported region. This doesn't change your environment's region. Contact Appian Support to learn more. Search result limits Smart search can return up to 100 results per search. To refine results, filter by a similarity score above a set threshold, sort by similarity score in descending order, and use a batch size of 10 or 20 to focus on the most relevant matches. Record size limits Smart search supports up to: 1 million records per record type for text fields 100,000 records per record type for extra long text fields 100,000 records per record type for document fields Field limitations You can configure one of the following per record type:: Up to three text fields One extra long text field and one text field One document field and one text field Note that enabling document or extra long text fields reduces the maximum supported number of indexed rows compared to using only text fields. This limit helps ensure smart search runs efficiently. Choose the fields that will provide the most value for your searches. Supported field types Text fields: Text fields usually contain less data than document fields, so they index more quickly. For example, indexing one million records with 4,000 characters each can take about 9 to 10 hours the first time they are indexed. Extra long text fields: Extra long text fields can store up to 64,000 characters, which is significantly more data than text fields. Because they contain more data than text fields but less than document fields, they index more slowly than text fields but more quickly than document fields. To improve indexing performance, consider using text fields when full extra long text content is not required. Document fields: Document fields typically contain more data than text fields, so they may take longer to index. For example, indexing 100,000 records that each include a 3 MB PDF may take up to 24 hours. Larger documents may take even longer. To improve indexing performance, consider using text fields when full document content is not required. A full indexing of all rows occurs only when you deploy record types or update the fields enabled for smart search. Scheduled syncs after that are typically faster because they only index data that has changed since the last data sync. While document files up to 5MB are technically supported, performance is not guaranteed and should be validated in your environment. Documents over 5MB or in unsupported formats will cause indexing to fail, which will take smart search offline. Smart search data updates After you enable smart search on a field in your record type, data becomes searchable shortly after a sync takes place on the record type. There are several key processes where data can be updated. Review the Data updates and Indexing sections for more details. Supported document formats DOCX HTML MD PDF (not image-based or scanned) TXT Note: Documents over 5MB or in unsupported formats will cause indexing to fail, which will take smart search offline. Enable smart search To start using smart search, you need to choose the fields you want to make searchable. These fields should contain the type of information users typically search for, such as detailed descriptions, comments, or notes. Focus on fields with rich, meaningful content to maximize the feature's effectiveness. To select fields for smart search: In the record type, go to Smart Search. Choose one of the following: up to three text fields, one extra long text field and one text field, or one Document type field and one text field. Tip: You can only choose one other text field if you choose an extra long text field or a document field. To enable smart search for documents, the document ID must use the Document field type. See Manage Documents with Record Types for more information about and best practices regarding the Document field type. Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close Click SAVE. Result: The fields you selected are indexed automatically. Saving triggers a data sync, which then starts the indexing process for smart search. Tip: You can check the indexing status on the Smart Search tab on the record type's Sync History page or on the Record Sync Status tab in the Monitor view. Add smart search to any query in your data fabric To add smart search to a query, use the search operator in a!queryFilter(). You can apply it within a!queryRecordType() or in a!recordData() when configuring a read-only grid. The search operator is a specialized operator designed to work with these functions. The search operator is not compatible with other functions or parameters. To use smart search on a read-only grid, set the similarityScoreThreshold parameter to a value less than 1. For example:0.0026. Also make sure the showSearchBox parameter is set to true. See the Using smart search topic on the Read-Only Grid Component page for more detailed information. To use smart search in a!queryRecordType, use a!queryFilter with a search operator. You can also use searchResults.allSearchFields.similarityScore as a field inside a!queryFilter to filter out semantically weak matches. For example a!queryFilter(field: recordType!Case.searchResults.allSearchFields.similarityScore; operator: ">=", value: 0.0026). Note: Smart search works when you search for the same term across multiple fields. It doesn't support searching for different terms in different fields. For example: Works: Searching for "power outage" in both the case title and description. Doesn't work: Searching for "power outage" in the title and "case closed" in the description. Sorting and filtering tips Keep these key points in mind when sorting and filtering search results: When using searchResults, you can only sort or filter by similarityScore. To enable sorting on a searchResults field, include the searchResults fields in the list of selected fields. You don't need to include the similarityScore field in the fields parameter to filter a query successfully. However, include it if you also want to display the field in the query results. We recommend always adding a filter on searchResults.allSearchFields to limit the number of searchResults. Alternatively, you can add interface components such as a dropdown with multiple similarity score thresholds, to allow users to specify the similarityScore that meets their needs. If needed, you can use the allSearchFields map from searchResults to sort and display search results in an interface. This approach is useful for customizing the presentation of search data. For example, you could sort by sourceContent instead of the similarityScore. The following example shows how to extract the allSearchFields map locally using a!queryRecordType, then re-sort the results by sourceContent for display purposes: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 a!localVariables( local!searchResultsMap: a!queryRecordType( recordType: 'recordType!Case', fields: { recordType!Case.fields.id, recordType!Case.fields.title, recordType!Case.fields.description, recordType!Case.searchResults.allSearchFields }, filters: a!queryLogicalExpression( operator: "AND", filters: { a!queryFilter( field: recordType!Case.fields.title, operator: "search", value: "vpn problems" ) }, ignoreFiltersWithEmptyValues: true ), pagingInfo: a!pagingInfo( startIndex: 1, batchSize: 100, sort: { a!sortInfo( field: recordType!Case.searchResults.allSearchFields.similarityScore ) } ) + /* Index into 'allSearchFields' to return a Map */ ).data[recordType!Case.searchResults.allSearchFields], + /* Convert the map to a datasubset and sort by `sourceContent`, which can't be done in a!queryRecordType */ todatasubset( arrayToPage: local!searchResultsMap, pagingConfiguration: a!pagingInfo( startIndex: 1, batchSize: 10, sort: a!sortInfo( field: "sourceContent", ascending: true ) ) ) ) Examples You can add smart search to a read-only grid using one of two approaches, depending on your needs and how much control you want over the search experience. Use the default search box: This recommended approach enables both keyword and smart search. Use this method when you want a simple way to surface relevant results without building a custom search interface. Use a your own custom search box: If you need more control over the UI or search logic, this approach gives you more flexibility over the search experience. Using smart search with the default search box This is the quickest way to add smart search to a grid. We recommend using this approach to implement smart search because it gives you more flexibility and works in more situations. This approach combines keyword and smart search. Matches found by keyword search will have a similarity score of 1, while semantic matches returned by smart search typically have scores less than 1. For best results, sort your grid by similarity score in descending order. Search behavior in a!gridField The following points describe how Appian processes search queries in a!gridField (read-only grid component). By default, the a!gridField component search box uses keyword search. If smart search is enabled, Appian runs both keyword and smart searches. Keyword search matches return a similarityScore of exactly 1. Smart search matches return a similarityScore less than 1. To use the similarityScoreThreshold parameter in the a!gridField component, showSearchBox must be set to true. To use your own search box, set showSearchBox to false and apply filters with a!recordData. Once set up, the a!gridField component uses keyword search for all integer and text fields in the a!gridColumn, and smart search for text or document fields that have smart search enabled and are displayed in the grid. Add the default search box to a read-only grid In most cases, you should be able to leverage smart search on read-only grids by doing two things: Set the showSearchBox parameter to true. This is the default. Set the similarityScoreThreshold parameter to a value lower than 1. For example: 0.0026 to get semantic matches. Example expression The following example illustrates how to retrieve a list of support cases logged around the same time by different users. These support cases could potentially share the same root cause, helping you address related issues efficiently. The expression applies three filters to narrow down the results: The case description must mention "power outage" or related terms (e.g., power failure). The case must have been logged within the past three days. The similarity score of the description must be at least 0.0026, ensuring the results are relevant. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 a!gridField( labelPosition: "ABOVE", data: recordType!Case, /*Enables search, including smart search if available to customer */ showSearchBox: true, /*Filters out smart search matches under this threshold */ /*This similarity score is for example purposes only */ /*The similarity score you choose will depend on your data and search criteria */ similarityScoreThreshold: 0.0026 columns: { a!gridColumn( label: "Id", sortField: recordType!Case.fields.id, value: a!richTextDisplayField( value: { a!richTextItem( text: fv!row[recordType!Case.fields.id], link: a!recordLink( recordType: recordType!Case, identifier: fv!identifier ), linkStyle: "STANDALONE" ) } ), align: "END" ), a!gridColumn( label: "Title", sortField: recordType!Case.fields.title, value: a!defaultValue(fv!row[recordType!Case.fields.title], "-") ), a!gridColumn( label: "Description", sortField: recordType!Case.fields.description, value: a!defaultValue(fv!row[recordType!Case.fields.description], "-") ), /*Display labels or icons. Avoid displaying score similarity values to end users */ /*This similarity score range is for example purposes only */ /*The similarity scores you choose will depend on your data and search criteria */ a!gridColumn( label: "Score", sortField: recordType!Case.searchResults.allSearchFields.similarityScore, value: a!localVariables( local!scoreValue: fv!row[recordType!Case.searchResults.allSearchFields.similarityScore], local!circleCount: {1,1,1}, local!color: a!match( value: local!scoreValue, whenTrue: fv!value = 1, then: "#0f90FF", whenTrue: fv!value >= 0.00389, then: "#0f9037", whenTrue: and(fv!value >= 0.0027, fv!value < 0.00389), then: "#119f3d", whenTrue: and(fv!value >= 0.0025, fv!value < 0.0027), then: "#12a740", default:"#83f9a8" ), if(a!isNullOrEmpty(local!scoreValue), "---", a!richTextDisplayField( value: a!forEach( items: local!circleCount, expression: a!richTextIcon( icon: "circle", color: local!color ) ), /*This similarity score range is for example purposes only */ /*The similarity scores you choose will depend on your data and search criteria */ tooltip: a!match( value: local!scoreValue, whenTrue: fv!value = 1, then: "Keyword Match", whenTrue: fv!value >= 0.00389, then: "Great", whenTrue: and(fv!value >= 0.0027, fv!value < 0.00389), then: "Good", whenTrue: and(fv!value >= 0.0025, fv!value < 0.0027), then: "Ok", default:"Not good" ) ) ) ) ) }, initialSorts: { /*Sorts by similarity score in descending order if applicable*/ a!sortInfo( field: recordType!Case.searchResults.allSearchFields.similarityScore, ascending: false() ), /* Defaults to sorting by primary key */ a!sortInfo( field: recordType!Case.fields.id, ascending: true ) } ) Example using your own search box If you want more flexibility over the search experience—for example, if you want to add filters, buttons, or custom styling—you can build your own search box. Use this method when you need fine-grained control over the search experience or want to integrate smart search into a larger filtering workflow. Create a custom search box in a read-only grid To build a custom smart search experience, use a!gridField() with a!recordData() and configure your own query logic. Follow these steps: Hide the default search box. 1 2 3 4 a!gridField( showSearchBox: false, /* other grid settings */ ) Fetch data with a!recordData(): Pass in your record type, filters, paging, and sorting. Enable smart search with the search operator 1 2 3 4 5 6 a!queryFilter( field: 'recordType!SSTA Case.fields.title', operator: "search", value: local!searchTerm, applyWhen: a!isNotNullOrEmpty(local!searchTerm) ) Add any custom filters (status, priority, date ranges, etc.). 1 2 3 4 5 6 a!queryFilter( field: 'recordType!Case.relationships.Status.fields.Id', operator: "in", value: local!statusSelection, applyWhen: a!isNotNullOrEmpty(local!statusSelection) ) (Optional) Include a similarity score filter using the similarityScore field to prioritize relevant results. For example: 1 2 3 4 5 a!queryFilter( field: 'recordType!Case.searchResults.document.similarityScore', operator: ">=", value: 0.00209, ) Note: Do not use the similarityScoreThreshold parameter. Example expression This example uses custom filters to create a tailored search and filtering experience for support cases. Instead of using the standard keyword search, the design uses smart search only and searches across the case title and description with additional filters for case status and priority. It also applies a minimum similarity score to prioritize more relevant search results. This approach provides your users with fine-grained control over the results, ensuring that the grid displays only high-quality matches that meet specific filter criteria. Note: This expression includes detailed inline comments to explain how search behavior and filtering are handled. Make sure to review the comments carefully to understand why certain configurations, such as custom filters and the similarity score threshold, are applied. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 a!localVariables( /* searchTerm: stores the user's free-text search input */ local!searchTerm, /* searchThreshold: minimum similarity score to include records */ local!searchThreshold: 0.0025, /* Loads the available case statuses so they can be used in the filter checkboxes*/ local!statusList: a!queryRecordType( recordType: recordType!SSTA Case Status, pagingInfo: a!pagingInfo( startIndex: 1, batchSize: 50 ) ), /* Keeps track of which status IDs the user has selected */ local!statusSelection, /* Loads the available case priorities so they can populate the filter checkboxes */ local!priorityList: a!queryRecordType( recordType: recordType!SSTA Case Priority, pagingInfo: a!pagingInfo( startIndex: 1, batchSize: 50 ) ), /* Keeps track of which priority IDs the user has selected */ local!prioritySelection, /* Main container for the Support Cases UI */ a!sectionLayout( label: "Support Cases", contents: { a!columnsLayout( columns: { /* Left column: Search & Filter card */ a!columnLayout( contents: { a!cardLayout( contents: { a!sectionLayout( label: "Search & Filter", labelSize: "SMALL", contents: { /* A search bar that includes a text field for entering your query, a clear icon to reset it, and an optional button to perform the search */ a!sideBySideLayout( items: { a!sideBySideItem( /* Text field for searchTerm, saved on blur */ item: a!textField( label: "", labelPosition: "ABOVE", placeholder: "Search case title or desc.", value: local!searchTerm, saveInto: local!searchTerm, refreshAfter: "UNFOCUS", validations: {} ), width: "6X" ), a!sideBySideItem( /* Icon to clear the searchTerm */ item: a!richTextDisplayField( value: { a!richTextIcon( icon: "window-close", link: a!dynamicLink( saveInto: a!save(local!searchTerm, "") ), color: "ACCENT" ) }, align: "LEFT", marginBelow: "LESS" ), width: "1X" ), a!sideBySideItem( /* (Optional) manual search button */ item: a!buttonArrayLayout( buttons: { a!buttonWidget( label: "", icon: "search", size: "SMALL" ) }, align: "START", marginBelow: "NONE" ), width: "1X" ) }, alignVertical: "BOTTOM", spacing: "DENSE", marginAbove: "NONE", stackWhen: {"PHONE"} ), /* Collapsible filters section */ a!sectionLayout( label: "Filters", labelIcon: "filter", labelSize: "EXTRA_SMALL", contents: { /* Status checkbox list */ a!checkboxField( choiceLabels: index( local!statusList.data, 'recordType!SSTA Case Status.fields.value' ), choiceValues: index( local!statusList.data, 'recordType!SSTA Case Status.fields.id' ), label: "Status", labelPosition: "ABOVE", value: local!statusSelection, saveInto: local!statusSelection, validations: {} ), /* Priority checkbox list */ a!checkboxField( choiceLabels: index( local!priorityList.data, 'recordType!SSTA Case Priority.fields.value' ), choiceValues: index( local!priorityList.data, 'recordType!SSTA Case Priority.fields.id' ), label: "Priority", labelPosition: "ABOVE", value: local!prioritySelection, saveInto: local!prioritySelection, validations: {} ) }, isCollapsible: true, isInitiallyCollapsed: false ) }, marginAbove: "NONE" ) }, height: "EXTRA_TALL", style: "STANDARD", marginBelow: "STANDARD", decorativeBarPosition: "NONE" ) } ), /* Results grid that displays search results for both the 'title' and 'description' fields using an OR operator*/ a!columnLayout( contents: { a!gridField( labelPosition: "ABOVE", data: a!recordData( recordType: recordType!SSTA Case, filters: a!queryLogicalExpression( operator: "AND", logicalExpressions: a!queryLogicalExpression( operator: "OR", filters: { /* Search title if searchTerm is present */ a!queryFilter( field: recordType!SSTA Case.fields.title, operator: "search", value: local!searchTerm, applyWhen: a!isNotNullOrEmpty(local!searchTerm) ), /* Search description if searchTerm is present */ a!queryFilter( field: recordType!SSTA Case.fields.description, operator: "search", value: local!searchTerm, applyWhen: a!isNotNullOrEmpty(local!searchTerm) ) } ), filters: { /* Additional filter for similarity score. Only includes records whose similarity score meets or exceeds the specified threshold, filtering out less relevant matches */ a!queryFilter( field: recordType!SSTA Case.searchResults.allSearchFields.similarityScore, operator: ">=", value: local!searchThreshold, applyWhen: a!isNotNullOrEmpty(local!searchTerm) ), /* Filter by selected statuses */ a!queryFilter( field: recordType!SSTA Case.relationships.status.fields.id, operator: "in", value: local!statusSelection, applyWhen: a!isNotNullOrEmpty(local!statusSelection) ), /* Filter by selected priorities */ a!queryFilter( field: recordType!SSTA Case.relationships.priority.fields.id, operator: "in", value: local!prioritySelection, applyWhen: a!isNotNullOrEmpty(local!prioritySelection) ) } ) ), columns: { /* No similarityScoreThreshold. Since you manually filter based on similarityScore and are not using the keyword search box, you cannot use similarityScoreThreshold directly as a property */ a!gridColumn( label: "Id", sortField: recordType!SSTA Case.fields.id, value: a!richTextDisplayField( value: { a!richTextItem( text: if( index(fv!row, recordType!SSTA Case.fields.id) < 100000, text( index(fv!row, recordType!SSTA Case.fields.id), "#00" ), index(fv!row, recordType!SSTA Case.fields.id) ), link: a!recordLink( recordType: recordType!SSTA Case, identifier: fv!identifier ), linkStyle: "STANDALONE" ) } ), width: "NARROW" ), /* Title column: shows placeholder if empty */ a!gridColumn( label: "Title", sortField: recordType!SSTA Case.fields.title, value: a!defaultValue( index(fv!row, recordType!SSTA Case.fields.title), "-" ), width: "NARROW_PLUS" ), /* Description column: shows placeholder if empty */ a!gridColumn( label: "Description", sortField: recordType!SSTA Case.fields.description, value: a!defaultValue( index(fv!row, recordType!SSTA Case.fields.description), "-" ), width: "MEDIUM" ), /* Shows each case's current status in the Status column */ a!gridColumn( label: "Status", sortField: recordType!SSTA Case.relationships.status.fields.value, value: index( fv!row, recordType!SSTA Case.relationships.status.fields.value ), width: "NARROW" ), /* Uses colored tags to display each case's priority in the Priority column */ a!gridColumn( label: "Priority", sortField: recordType!SSTA Case.relationships.priority.fields.value, value: if( isnull( index(fv!row, recordType!SSTA Case.relationships.priority) ), "-", a!tagField( tags: { a!tagItem( text: index( fv!row, recordType!SSTA Case.relationships.priority.fields.value ), /* Tag background color chosen by priority ID */ backgroundColor: a!match( value: index( fv!row, recordType!SSTA Case.relationships.priority.fields.id ), equals: 1, then: "#e4fcdc", equals: 2, then: "#fcefca", equals: 3, then: "#fcdcdc", default: "#f0f0f0" ), textColor: "STANDARD" ) } ) ), align: "CENTER", width: "NARROW" ), /* Uses up to three colored circles in the Score column to represent each record's similarity score.*/ a!gridColumn( label: "Score", sortField: recordType!SSTA Case.searchResults.allSearchFields.similarityScore, value: a!localVariables( /* Capture the raw similarityScore */ local!scoreValue: fv!row[recordType!SSTA Case.searchResults.allSearchFields.similarityScore], /* Number of circles to render */ local!circleCount: {1,1,1}, /* Determine circle color by score range */ local!color: a!match( value: local!scoreValue, whenTrue: fv!value >= 0.00389, then: "#0f9037", whenTrue: and(fv!value >= 0.0027, fv!value < 0.00389), then: "#119f3d", whenTrue: and(fv!value >= 0.0025, fv!value < 0.0027), then: "#12a740", default: "#83f9a8" ), /* Shows a placeholder when no score is available; otherwise, displays colored circles to represent the score */ if( a!isNullOrEmpty(local!scoreValue), "---", a!richTextDisplayField( value: a!forEach( items: local!circleCount, expression: a!richTextIcon(icon: "circle", color: local!color) ), tooltip: a!match( value: local!scoreValue, whenTrue: fv!value >= 0.00389, then: "Great", whenTrue: and(fv!value >= 0.0027, fv!value < 0.00389), then: "Good", whenTrue: and(fv!value >= 0.0025, fv!value < 0.0027), then: "Ok", default: "Not good" ) ) ) ) ) }, pagesize: 10, /* Sorts first by descending similarity, then ascending ID */ /*If a search term is present, sorts results by similarity score in descending order so better matches appear at the top of the grid */ initialSorts: { a!sortInfo( field: 'recordType!SSTA Case.searchResults.allSearchFields.similarityScore', ascending: false ), a!sortInfo( field: 'recordType!SSTA Case.fields.id', ascending: true() ) }, /* Refresh the grid after any record action (edit, save, etc.) */ refreshAfter: "RECORD_ACTION", /* Hides the keyword search box because you have custom filters */ showSearchBox: false, validations: {} ) }, width: "4X" ) } ) } ) ) Here's what the interface looks when you use this expression. Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close Search results (returns) When you run a query that includes smart search, the returned DataSubset includes the following fields: similarityScore sourceContent searchMatches (extra-long text and document fields only) You can access similarity scores and related search information directly from the DataSubset results. For example, suppose you run the following query: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 a!queryRecordType( recordType: recordType!Case, fields: { recordType!Case.fields.id, recordType!Case.fields.title, recordType!Case.fields.description, /* Returns similarityScore and sourceContent for the title field */ recordType!Case.searchResults.title, /* Returns similarityScore and sourceContent for the description field */ recordType!Case.searchResults.description, /* Returns similarityScore, sourceContent and sourceField for the field with the best semantic match */ /* In this case, could be title or description, because we are searching those two fields */ recordType!Case.searchResults.allSearchFields, }, filters: { a!queryFilter( field: recordType!Case.fields.title operator: "search", value: "software update" ), a!queryFilter( field: recordType!Case.fields.description operator: "search", value: "software update" ), }, pagingInfo: a!pagingInfo( startIndex: 1, batchSize: 2, sort: { /*Sort by similarity score so the best matches are returned at the top*/ a!sortInfo( field: recordType!Case.searchResults.allSearchFields.similarityScore, ascending: false ) } ) ) The results would look something like this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 data (List of Case) Case id: 2 title: "Software update failure" description: "Attempted to update ERP system, update failed midway. Rolled back to previous version." searchResults.allSearchFields similarityScore: 0.003823 sourceContent: "Attempted to update ERP system, update failed midway. Rolled back to previous version." sourceField: description searchResults.title similarityScore: null sourceContent: null searchResults.description similarityScore: 0.003823 sourceContent: "Attempted to update ERP system, update failed midway. Rolled back to previous version." Case id: 44 title: "Application errors after update" description: "Shortly after applying a software update to one of our internal web apps, users started reporting errors when accessing certain features. We've had to roll back the update but some issues persist." searchResults.allSearchFields similarityScore: 0.002546 sourceContent: "Shortly after applying a software update to one of our internal web apps, users started reporting errors when accessing certain features. We've had to roll back the update but some issues persist." searchResults.title similarityScore: null sourceContent: null searchResults.description similarityScore: 0.002546 sourceContent: "Shortly after applying a software update to one of our internal web apps, users started reporting errors when accessing certain features. We've had to roll back the update but some issues persist." Tip: A null similarity score in the title field means there was no semantic match. In this case, searchResults.allSearchFields matches searchResults.description because it contains the highest scoring match. The sourceField confirms this by pointing to the description field. Tips implementing using smart search Use these tips to get the most out of smart search and return more relevant results in your queries. Verify the fields you want to search are enabled for smart search. Make sure the smart search indexing status is Completed and not Failed or Running. Search time increases as the number of records and searchable fields grows. To improve performance, limit the number of fields and records being searched when possible. For example, searching 10,000 records is faster than searching 1 million records. Use allSearchFields.similarityScore whenever possible to sort and filter. Only use <<fieldName>>.similarityScore if your use case requires it. This field behaves like related records and may return unexpected results without a search. Add logic to check for a search term first. Don't filter or sort by sourceContent. sourceContent is designed to be a result of the search, not a criteria for filtering or sorting. Monitor smart search index statuses You can monitor the indexing status of your record type in two places: The Smart Search tab on the record type's Sync History page. This view shows the indexing history specific to smart search for that record type. Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close The Record Sync Status tab in the Monitoring View. This view shows the latest smart search status for each record type that has smart search enabled. Scroll or drag to pan · ⌘+/⌘− to zoom · Esc to close Use these views to confirm that smart search is successfully indexing your data. If the status shows an error or indicates that indexing is incomplete, smart search results may be outdated or missing. Indexing statuses Indexing can have one of the following statuses, depending on its current state: Note: This status reflects the smart search indexing only, which is separate from the sync status of the record type. Pending: Smart search is enabled but indexing hasn't started because the initial sync is still in progress. Running: The system is currently indexing data for smart search. If an initial data indexing attempt fails, Appian will automatically retry a few times. While retrying, smart search remains available but may have slightly outdated data. If all retries fail, smart search will become unavailable. Completed: Indexing is finished and all data is available for smart search. Approaching Limit: The record type is indexed but is nearing the indexed row limit (90% or more of the maximum). Limit Reached: The record type is indexed but it has reached the maximum indexed row limit (100%). Failed: Indexing did not complete successfully. Check the system logs or error messages for more details. Skipped: Indexing was skipped due to a data sync failure. If Skip failed syncs is enabled, search may still use the last successful index. Check the smart search status history and sync logs. Resolve the sync failure to resume indexing. Troubleshooting This section helps you identify and resolve issues that can prevent smart search from indexing your data correctly. Smart search is offline If smart search is unavailable for your record type, it may be due to indexing failures. Indexing may fail when: A sync failed on the record type. To resolve indexing issues and bring smart search back online, you must resolve the sync issue and sync the record type. The record type tries to index too many rows for a specific field type. Each field type can index a maximum of: Text fields: 1 million rows. Extra long text fields: 100,000 rows. Document fields: 100,000 rows. A document is over 5MB in size or is an unsupported format. When indexing fails on the record type, the indexing status is set as Failed. See how to troubleshoot these failures. Unable to find relevant search results While smart search understands the meaning and intent behind your terms, it's important to remember that smart search is not a conversational chatbot like data fabric chatbot. Smart search will only find the most relevant information based on your search terms. You may not see the results you're expecting if you use smart search like a chatbot. When using smart search: DO describe what you're looking for using a couple of key terms or a full phrase. The more context you provide, the more relevant your results will be. Example: Search for terms like Paid time off, PTO, or vacation policy. DON'T attempt to have a conversation with the search. Example: A search for What is our PTO policy? may find the Paid Time Off Guidelines document. However, it will not reply, "You have 15 days of PTO." Feedback Was this page helpful? SHARE FEEDBACK Loading...