diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 5bac8f9e67..8ad2e4f991 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -567,7 +567,7 @@ getting_started_communicating_with_a_protected_instance: |- curl \ -X POST 'http://localhost:7700/indexes/movies/search' \ -H 'Authorization: Bearer API_KEY' -faceted_search_update_settings_1: |- +filtering_update_settings_1: |- curl \ -X PATCH 'http://localhost:7700/indexes/movie_ratings/settings' \ -H 'Content-Type: application/json' \ @@ -993,3 +993,73 @@ swap_indexes_1: | ] } ]' +multi_search_1: |- + curl \ + -X POST 'http://localhost:7700/multi-search' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "queries": [ + { + "indexUid": "movies", + "q": "pooh", + "limit": 5 + }, + { + "indexUid": "movies", + "q": "nemo", + "limit": 5 + }, + { + "indexUid": "movie_ratings", + "q": "us" + } + ] + }' +faceted_search_update_settings_1: |- + curl \ + -X PUT 'http://localhost:7700/indexes/books/settings/filterable-attributes' \ + -H 'Content-Type: application/json' \ + --data-binary '[ + "genres", "rating", "language" + ]' +faceted_search_1: |- + curl \ + -X POST 'http://localhost:7700/indexes/books/search' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "q": "classic", + "facets": [ + "genres", "rating", "language" + ] + }' +search_parameter_guide_facet_stats_1: |- + curl \ + -X POST 'http://localhost:7700/indexes/movie_ratings/search' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "q": "Batman", + "facets": ["genres", "rating"] + }' +faceted_search_2: |- + curl \ + -X POST 'http://localhost:7700/multi-search' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "queries": [ + { + "indexUid": "books", + "facets": ["language", "genres", "author", "format"], + "filter": "(language = English AND language = French) OR genres = Fiction" + }, + { + "indexUid": "books", + "facets": ["language"], + "filter": "genres = Fiction" + }, + { + "indexUid": "books", + "facets": ["genres"], + "filter": "language = English OR language = French" + } + ] + }' diff --git a/.vuepress/config.js b/.vuepress/config.js index 5f0c0c0bcd..94573764c0 100644 --- a/.vuepress/config.js +++ b/.vuepress/config.js @@ -74,6 +74,7 @@ module.exports = { { text: 'GitHub', link: 'https://github.com/meilisearch/meilisearch' }, { text: 'Discord', link: 'https://discord.gg/meilisearch' }, { text: 'Blog', link: 'https://blog.meilisearch.com/' }, + { text: 'Awesome Meilisearch', link: 'https://github.com/meilisearch/awesome-meilisearch' }, { text: 'meilisearch.com', link: 'https://meilisearch.com' }, ], }, @@ -189,7 +190,8 @@ module.exports = { collapsable: false, children: [ '/learn/advanced/asynchronous_operations', - '/learn/advanced/filtering_and_faceted_search', + '/learn/advanced/filtering', + '/learn/advanced/faceted_search', '/learn/advanced/geosearch', '/learn/advanced/pagination', '/learn/advanced/sorting', @@ -318,6 +320,7 @@ module.exports = { '/reference/api/indexes', '/reference/api/documents', '/reference/api/search', + '/reference/api/multi_search', '/reference/api/tasks', '/reference/api/keys', '/reference/api/settings', diff --git a/.vuepress/public/_redirects b/.vuepress/public/_redirects index 80a2e5608d..a6b03d79d9 100644 --- a/.vuepress/public/_redirects +++ b/.vuepress/public/_redirects @@ -11,8 +11,8 @@ /guides/advanced_guides/installation.html /learn/getting_started/installation.html /guides/advanced_guides/configuration.html /learn/configuration/instance_options.html /guides/advanced_guides/search_parameters.html /reference/api/search.html -/guides/advanced_guides/filtering.html /learn/advanced/filtering_and_faceted_search.html -/guides/advanced_guides/faceted_search.html /learn/advanced/filtering_and_faceted_search.html +/guides/advanced_guides/filtering.html /learn/advanced/filtering.html +/guides/advanced_guides/faceted_search.html /learn/advanced/faceted_search.html /guides/advanced_guides/authentication.html /learn/security/master_api_keys.html /guides/advanced_guides/asynchronous_updates.html /learn/advanced/asynchronous_operations.html /guides/advanced_guides/web_interface.html /learn/what_is_meilisearch/search_preview.html @@ -77,8 +77,8 @@ # Group filters and facets content /reference/api/attributes_for_faceting.html /reference/api/settings.html -/reference/features/filtering.html /learn/advanced/filtering_and_faceted_search.html -/reference/features/faceted_search.html /learn/advanced/filtering_and_faceted_search.html +/reference/features/filtering.html /learn/advanced/filtering.html +/reference/features/faceted_search.html /learn/advanced/faceted_search.html # Rename Asynchronous updates to Asynchronous operations /learn/advanced/asynchronous_updates.html /learn/advanced/asynchronous_operations.html @@ -203,3 +203,10 @@ # New "Update and migration" section /learn/getting_started/algolia_migration.html /learn/update_and_migration/algolia_migration.html /learn/advanced/updating.html /learn/update_and_migration/updating.html + +# Move faceting to a new guide +/learn/advanced/filtering_and_faceted_search.html#faceted-search /learn/advanced/faceted_search.html + +# Rename filtering guide +/learn/advanced/filtering_and_faceted_search.html /learn/advanced/filtering.html + diff --git a/.vuepress/public/books.json b/.vuepress/public/books.json new file mode 100644 index 0000000000..c64ebee9fa --- /dev/null +++ b/.vuepress/public/books.json @@ -0,0 +1,146 @@ +[ + { + "id":5, + "title": "Hard Times", + "genres": ["Classics","Fiction", "Victorian", "Literature"], + "publisher": "Penguin Classics", + "language": "English", + "author": "Charles Dickens", + "description":"Hard Times is a novel of social protest which attacks utilitarianism, Bentham's theory which only considered the practical aspects of happiness and ignored emotional, spiritual and moral values. It is set in Coketown, a fictious industrial city in northern England in the mid-1800s.", + "format": "Hardcover", + "rating": 3 + }, + { + "id":1, + "title": "Don Quixote", + "genres": ["Satire","Fiction"], + "publisher": "Penguin Classics", + "language": "Spanish", + "author": "Miguel de Cervantes", + "description":"Don Quixote is a classic novel from 1605 which portraits the life and insightful journey of Don Quixote de la Mancha, a Spanish man who seems to be losing his mind on his quest to become a knight and restore chivalry alongside with a farmer named Sancho Panza, with whom he fights multiple imaginary ", + "format": "Hardcover", + "rating": 4 + }, + { + "id":2, + "title": "The Travels of Ibn Battuta", + "genres": ["Travel","Adventure"], + "publisher": "Dover Publications", + "language": "English", + "author": "Ibn Battuta", + "description":"His main reason to travel was to go on a Hajj, or a Pilgrimage to Mecca, to fulfill the fifth pillar of Isla.. But his traveling went on for around 29 years and he covered about 75,000 miles visiting the equivalent of 44 modern countries which were then mostly under the governments of Muslim leaders of the World of ", + "format": "Hardcover", + "rating": 4.5 + }, + { + "id":3, + "title": "Les Misérables", + "genres": ["Tragedy", "Fiction", "Novel", "Historical Fiction", "Literature", "Classics"], + "publisher": "Simon & Schuster", + "language": "French", + "author": "Victor Hugo", + "description":"Les Misérables centres on the character Jean Valjean, an ex-convict in 19th-century France. The story spans many years as it tells of Valjean's release from prison and reformation as an industrialist while being constantly pursued by the morally strict inspector Javert.", + "format": "Hardcover", + "rating": 4.7 + }, + { + "id":4, + "title": "James and the Giant Peach", + "genres": ["Novel","Children's Literature", "Fantasy"], + "publisher": "Puffin Books", + "language": "English", + "author": "Roald Dahl", + "description":"When his parents are unceremoniously eaten by a rhinoceros that escapes from London Zoo, James is forced to go and live with his unpleasant aunts. Through a series of peculiar and magical happenings, James finds himself in a giant peach with a bunch of friendly giant insects for travelling companions.", + "format": "Paperback", + "rating": 4 + }, + { + "id":6, + "title": "Pride and Prejudice", + "genres": ["Classics","Fiction", "Romance", "Literature"], + "publisher": "Penguin Classics", + "language": "English", + "author": "Jane Austen", + "description":"Pride and Prejudice follows the turbulent relationship between Elizabeth Bennet, the daughter of a country gentleman, and Fitzwilliam Darcy, a rich aristocratic landowner. They must overcome the titular sins of pride and prejudice in order to fall in love and marry.", + "format": "Hardcover", + "rating": 4 + }, + { + "id":7, + "title": "Diary of a Wimpy Kid", + "genres": ["Humor", "Fiction", "Young Adult", "Comedy","Diary Fiction"], + "publisher": "", + "language": "English", + "author": "Jeff Kinney", + "description":"It's a new school year, and Greg Heffley finds himself thrust into middle school, where undersized weaklings share the hallways with kids who are taller, meaner, and already shaving. The hazards of growing up before you're ready are uniquely revealed through words and drawings as Greg records them in his diary.", + "format": "Hardcover", + "rating": 4.8 + }, + { + "id":8, + "title": "Anne of Green Gables", + "genres": ["Literature", "Fiction", "Novel", "Comedy", "Coming-of-Age"], + "publisher": "Wordsworth Editions Ltd", + "language": "English", + "author": "Lucy M. Montgomery", + "description":"Anne of Green Gables, children's novel by Canadian author Lucy Maud Montgomery, published in 1908. The work, a sentimental but charming coming-of-age story about a spirited and unconventional orphan girl who finds a home with elderly siblings, became a classic of children's literature and led to several sequels.", + "format": "Hardcover", + "rating": 4 + }, + { + "id":9, + "title": "Harry Potter and the Chamber of Secrets", + "genres": ["Fantasy", "Fiction", "Magic", "Adventure", "Young Adult"], + "publisher": "Bloomsbury Publishing PLC", + "language": "English", + "author": "J.K. Rowling", + "description":"The second instalment of boy wizard Harry Potter's adventures at Hogwarts School of Witchcraft and Wizardry, based on the novel by JK Rowling. A mysterious elf tells Harry to expect trouble during his second year at Hogwarts, but nothing can prepare him for trees that fight back, flying cars, spiders that talk and deadly warnings written in blood on the walls of the school.", + "format": "Paperback", + "rating": 2 + }, + { + "id":10, + "title": "David Copperfield", + "genres": ["Classics","Fiction", "Victorian", "Literature"], + "publisher": "Penguin UK", + "language": "English", + "author": "Charles Dickens", + "description":"The story follows the life of David Copperfield from childhood to maturity. David was born in Blunderstone, Suffolk, England, six months after the death of his father. David spends his early years in relative happiness with his loving, childish mother and their kindly housekeeper, Clara Peggotty.", + "format": "Hardcover", + "rating": 3.9 + }, + { + "id":11, + "title": "Dracula", + "genres": ["Classics","Fiction", "Horror", "Literature", "Vampires", "Fantasy"], + "publisher": "Penguin UK", + "language": "English", + "author": "Bram Stoker", + "description":"Dracula is a gothic novel by Bram Stoker published in 1897. Stoker tells the story of the fight against the vampire Dracula in an epistolary format. The story comprises various letters, telegrams, journal entries, and newspaper articles written by the main characters.", + "format": "Hardcover", + "rating": 2.5 + }, + { + "id":12, + "title": "Frankenstein", + "genres": ["Classics","Fiction", "Horror", "Literature", "Fantasy"], + "publisher": "Penguin UK", + "language": "English", + "author": "Mary Shelley", + "description":"Frankenstein tells the story of gifted scientist Victor Frankenstein who succeeds in giving life to a being of his own creation. However, this is not the perfect specimen he imagines that it will be, but rather a hideous creature who is rejected by Victor and mankind in general.", + "format": "Hardcover", + "rating": 3 + }, + { + "id":13, + "title": "Madame Bovary", + "genres": ["Novel","Fiction", "Realism", "Literature"], + "publisher": "Penguin UK", + "language": "French", + "author": "Gustave Flaubert", + "description":"Madame Bovary is the debut novel of French writer Gustave Flaubert, published in 1856. The character lives beyond her means in order to escape the banalities and emptiness of provincial life. When the novel was first serialized in La Revue de Paris between 1 October 1856 and 15 December 1856, public prosecutors attacked the novel for obscenity. The resulting trial in January 1857 made the story notorious. After Flaubert's acquittal on 7 February 1857, Madame Bovary became a bestseller in April 1857 when it was published in two volumes. A seminal work of literary realism, the novel is now considered Flaubert's masterpiece, and one of the most influential literary works in history.", + "format": "Hardcover", + "rating": 4 + } +] + \ No newline at end of file diff --git a/.vuepress/public/faceted-search/conjunctive-and-disjunctive-facets.gif b/.vuepress/public/faceted-search/conjunctive-and-disjunctive-facets.gif new file mode 100644 index 0000000000..44435eacd0 Binary files /dev/null and b/.vuepress/public/faceted-search/conjunctive-and-disjunctive-facets.gif differ diff --git a/.vuepress/public/faceted-search/conjunctive-factes.gif b/.vuepress/public/faceted-search/conjunctive-factes.gif new file mode 100644 index 0000000000..690eb1d64d Binary files /dev/null and b/.vuepress/public/faceted-search/conjunctive-factes.gif differ diff --git a/.vuepress/public/faceted-search/disjunctive_facets.gif b/.vuepress/public/faceted-search/disjunctive_facets.gif new file mode 100644 index 0000000000..6bcca22251 Binary files /dev/null and b/.vuepress/public/faceted-search/disjunctive_facets.gif differ diff --git a/.vuepress/public/faceted-search/facets-ecommerce.png b/.vuepress/public/faceted-search/facets-ecommerce.png index 43203d404a..e214f59cd7 100644 Binary files a/.vuepress/public/faceted-search/facets-ecommerce.png and b/.vuepress/public/faceted-search/facets-ecommerce.png differ diff --git a/.vuepress/public/faceted-search/multi-search.gif b/.vuepress/public/faceted-search/multi-search.gif new file mode 100644 index 0000000000..6228d0767c Binary files /dev/null and b/.vuepress/public/faceted-search/multi-search.gif differ diff --git a/.vuepress/public/sample-template.yaml b/.vuepress/public/sample-template.yaml index 66d6839b43..d04b47b133 100644 --- a/.vuepress/public/sample-template.yaml +++ b/.vuepress/public/sample-template.yaml @@ -84,7 +84,7 @@ getting_started_geo_radius: |- getting_started_geo_point: |- getting_started_sorting: |- getting_started_filtering: |- -faceted_search_update_settings_1: |- +filtering_update_settings_1: |- faceted_search_facets_1: |- faceted_search_walkthrough_filter_1: |- add_movies_json_1: |- @@ -157,3 +157,8 @@ async_guide_filter_by_index_uids_1: | cancel_tasks_1: | delete_tasks_1: | swap_indexes_1: | +multi_search_1: | +faceted_search_update_settings_1: |- +search_parameter_guide_facet_stats_1: |- +faceted_search_1: |- +faceted_search_2: |- diff --git a/LICENSE b/LICENSE index 744b049605..f19d2b4c1f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019-2022 Meili SAS +Copyright (c) 2019-2023 Meili SAS Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/learn/advanced/datatypes.md b/learn/advanced/datatypes.md index 9de5792eeb..46bc8d77ef 100644 --- a/learn/advanced/datatypes.md +++ b/learn/advanced/datatypes.md @@ -57,7 +57,7 @@ A numeric type (`integer`, `float`) is converted to a human-readable decimal num You can add [custom ranking rules](/learn/core_concepts/relevancy.md#custom-rules) to create an ascending or descending sorting rule on a given attribute that has a numeric value in the documents. -You can also create [filters](/learn/advanced/filtering_and_faceted_search.md). The `>`, `>=`, `<`, `<=`, and `TO` relational operators apply only to numerical values. +You can also create [filters](/learn/advanced/filtering.md). The `>`, `>=`, `<`, `<=`, and `TO` relational operators apply only to numerical values. ## Boolean diff --git a/learn/advanced/faceted_search.md b/learn/advanced/faceted_search.md new file mode 100644 index 0000000000..9e275e4f8b --- /dev/null +++ b/learn/advanced/faceted_search.md @@ -0,0 +1,208 @@ +--- + +sidebarDepth: 2 + +--- + +# Faceted search + +You can use Meilisearch filters to build faceted search interfaces. This type of interface allows users to refine search results based on broad categories or facets. Faceted search provides users with a quick way to narrow down search results by selecting categories relevant to what they are looking for. A faceted navigation system is an **intuitive interface to display and navigate through content**. + +Facets are common in ecommerce sites like Amazon. When users search for products, they are presented with a list of results and a list of facets which you can see on the sidebar in the image below: + +![Meilisearch demo for an ecommerce website displaying faceting UI](/faceted-search/facets-ecommerce.png) + +Faceted search interfaces often have a count of how many results belong to each facet. This gives users a visual clue of the range of results available for each facet. + +### Filters or facets + +Meilisearch does not differentiate between facets and filters. Facets are a specific use-case of filters, meaning you can use any attribute added to `filterableAttributes` as a facet. Whether something is a filter or a facet depends above all on UX and UI design. + +## Configuring and using facets + +Like any other filter, you must add any attributes you want to use as facets to the [`filterableAttributes`](/reference/api/settings.md#filterable-attributes) list in an index's settings. Once you have configured `filterableAttributes`, you can search for facets with [the `facets` search parameter](/reference/api/search.md#facets). + +::: warning +Synonyms don't apply to facets. If you have `SF` and `San Francisco` set as synonyms, faceting by `SF` and `San Francisco` will show you different results. +::: + +Suppose you have a books dataset containing the following fields: + +```json +{ + "id":5, + "title": "Hard Times", + "genres": ["Classics","Fiction", "Victorian", "Literature"], + "publisher": "Penguin Classics", + "language": "English", + "author": "Charles Dickens", + "description":"Hard Times is a novel of social … ", + "format": "Hardcover", + "rating": 3 +} +``` + +The following code sample allows you to create facets for the `genres`, `language`, and `rating` attributes: + + + +Now, if you were to search the `books` index for `classic` using the following code sample: + + + +The response would return `classic` books along with two new fields: [`facetDistribution`](#facet-distribution) and [`facetStats`](#facet-stats): + +```json +{ + "hits":[ + … + ], + "query":"classic", + … + "facetDistribution":{ + "genres":{ + "Classics":6, + … + }, + "language":{ + "English":6, + "French":1, + "Spanish":1 + }, + "rating":{ + "2.5":1, + … + } + }, + "facetStats":{ + "rating":{ + "min":2.5, + "max":4.7 + } + } +} +``` + +### Facet distribution + +The `facetDistribution` object contains the number of matching documents distributed among the values of a given facet. Meilisearch automatically adds `facetDistribution` to the response of any query using the `facets` search parameter. + +The following response shows the facet distribution when searching for `classics`: + +```json +{ + … + "facetDistribution":{ + "genres":{ + "Classics":6, + "Comedy":1, + "Coming-of-Age":1, + "Fantasy":2, + "Fiction":8, + … + }, + "language":{ + "English":6, + "French":1, + "Spanish":1 + }, + "rating":{ + "2.5":1, + "3":2, + "3.9":1, + "4":3, + "4.7":1 + } + }, + … +} +``` + +`facetDistribution` contains an object for every attribute passed to the `facets` parameter. Each object contains the different values for that attribute and the count of matching documents with that value. Meilisearch does not return empty facets: if there are no results for the Arabic language, it will not be present in `facetDistribution`. + +::: note +By default, `facets` returns a maximum of 100 facet values for each faceted field. You can change this value using the `maxValuesPerFacet` property of the [`faceting` index settings](/reference/api/settings.md#faceting). +::: + +### Facet stats + +When using the `facets` parameter, Meilisearch results include a `facetStats` object. `facetStats` contains the lowest (`min`) and highest (`max`) numerical values across all documents in each facet. + +`facetStats` is useful when creating UI components such as range sliders. These allow users to refine their search by selecting from a range of facet values. + +::: note +Meilisearch ignores numeric strings like `"21"` when computing `facetStats`. +::: + +The following response shows the lowest and highest book ratings when searching for `"classic"`: + +```json +{ + … +"facetStats":{ + "rating":{ + "min":2.5, + "max":4.7 + } + } + … +} +``` + +If none of the matching documents have a numeric value for a facet, that facet is not included in the `facetStats` object. Since `rating` was the only numeric facet in our example, it is the only facet returned in the `facetStats` object. + +## Facet types + +### Conjunctive facets + +Conjunctive facets use the `AND` logical operator. When users select multiple values for a facet, returned results must contain all selected facet values. + +With conjunctive facets, when a user selects `English` from the `language` facet, all returned books must be in English. If the user further narrows down the search by selecting `Fiction` and `Literature` as `genres`, all returned books must be in English and contain both `genres`. + +``` +"language = English AND genres = Fiction AND genres = Literature" +``` + +The GIF below shows how the facet count for `genres` updates to only include books that meet **all three conditions**. + +![Selecting English books with 'Fiction' and 'Literature' as 'genres' for the books dataset](/faceted-search/conjunctive-factes.gif) + +### Disjunctive facets + +Disjunctive facets use the `OR` logical operator. When users select multiple values for a facet, returned results must contain at least one of the selected values. + +With disjunctive facets, when a user selects `Fiction`, and `Literature`, Meilisearch returns all books that are either `Fiction`, `Literature`, or both: + +``` +"genres = Fiction OR genres = Literature" +``` + +The GIF below shows the `books` dataset with disjunctive facets. Notice how the facet count for `genres` updates based on the selection. + +![Selecting 'Fiction' and 'Literature' as 'genres' for the books dataset](/faceted-search/disjunctive_facets.gif) + +### Combining conjunctive and disjunctive facets + +It is possible to create search queries with both conjunctive and disjunctive facets. + +For example, a user might select `English` and `French` from the `language` facet so they can see books written either in English or in French. This query uses an `OR` operator and is a disjunctive facet: + +``` +"language = English OR language = French" +``` + +The same user might also be interested in literary fiction books and select `Fiction` and `Literature` as `genres`. Since the user wants a specific combination of genres, their query uses an `AND` operator: + +``` +"genres = Fiction AND genres = Literature" +``` + +The user can combine these two filter expressions in one by wrapping them in parentheses and using an `AND` operator: + +``` +"(language = English OR language = French) AND (genres = Fiction AND genres = Literature)" +``` + +The GIF below shows the `books` dataset with conjunctive and disjunctive facets. Notice how the facet count for each facet updates based on the selection. + +![Selecting 'Fiction' and 'Literature' as 'genres' for English books](/faceted-search/conjunctive-and-disjunctive-facets.gif) diff --git a/learn/advanced/filtering_and_faceted_search.md b/learn/advanced/filtering.md similarity index 78% rename from learn/advanced/filtering_and_faceted_search.md rename to learn/advanced/filtering.md index 96910e7076..3d95c61712 100644 --- a/learn/advanced/filtering_and_faceted_search.md +++ b/learn/advanced/filtering.md @@ -4,7 +4,7 @@ sidebarDepth: 2 --- -# Filtering and faceted search +# Filtering Filters have several use-cases, such as refining search results and creating faceted search interfaces. Faceted search interfaces are particularly efficient in helping users navigate a great number of results across many broad categories. @@ -35,7 +35,7 @@ Suppose you have a collection of movies called `movie_ratings` containing the fo If you want to filter results based on the `director` and `genres` attributes, you must first add them to the `filterableAttributes` list: - + **This step is mandatory and cannot be done at search time**. Updating `filterableAttributes` requires Meilisearch to re-configure your index, which will take an amount of time proportionate to your dataset size and complexity. @@ -367,67 +367,3 @@ Use dot notation to filter results based on a document's nested fields. The foll [You can read more about nested fields in our guide on data types.](/learn/advanced/datatypes.md) - -## Faceted search - -Meilisearch filters can be used to build **faceted search** interfaces. This type of interface allows users to refine search results based on broad categories or **facets**. For example, a clothing webshop can use faceted search to allow users to easily explore items of a certain size or belonging to a specific brand. - -Faceted search provides users with a quick way to narrow down search results by selecting categories relevant to what they are looking for. A faceted navigation system is an **intuitive interface to display and navigate through content**. Facets are used in the UI as filters that users can apply to refine the results in real-time. - -This is common in ecommerce sites like Amazon. When users perform a search, they are presented not only with a list of results but also with a list of facets which you can see on the sidebar in the image below: - -![Meilisearch demo for an ecommerce website displaying faceting UI](/faceted-search/facets-ecommerce.png) - -Faceted search interfaces often have a count of how many results belong to each facet. This gives users a visual clue of the range of results available for each facet. - -### Filters or facets - -In Meilisearch, facets are a specific use-case of filters. The question of whether something is a filter or a facet is mostly one pertaining to UX and UI design. - -### Configuring and using facets - -Like any other filter, attributes you want to use as facets must be added to the [`filterableAttributes` list](/reference/api/settings.md#filterable-attributes) in the index's settings before they can be used. - -Once they have been configured, you can search for facets with [the `facets` search parameter](/reference/api/search.md#facets). - -::: warning -Synonyms don't apply to facets. Meaning, if you have `SF` and `San Francisco` set as synonyms, filtering by `SF` and `San Francisco` will show you different results. -::: - -::: note -Meilisearch does not differentiate between facets and filters. This means that, despite its name, `facets` can be used with any attributes added to `filterableAttributes`. -::: - -#### Facet distribution - -Using `facets` will add an extra field,`facetDistribution`, to the returned search results containing the number of matching documents distributed among the values of a given facet. The `facets` search parameter expects an array of strings. Each string is an attribute present in the `filterableAttributes` list. - -The following search query gives you the distribution of `batman` movies per genre: - - - -```json -{ - "hits": [ - … - ], - … - "facetDistribution": { - "genres": { - "action": 273, - "animation": 118, - "adventure": 132, - "fantasy": 67, - "comedy": 475, - "mystery": 70, - "thriller": 217 - } - } -} -``` - -`facetDistribution` contains an object for every given facet. For each of these facets, there is another object containing all the different values and the count of matching documents. Note that zero values will not be returned: if there are no `romance` movies matching the query, `romance` is not displayed. - -::: note -By default, `facets` returns a maximum of 100 facet values for each faceted field. You can change this value using the `maxValuesPerFacet` property of the [`faceting` index settings](/reference/api/settings.md#faceting). -::: diff --git a/learn/advanced/geosearch.md b/learn/advanced/geosearch.md index b0193ecd87..78924c01bf 100644 --- a/learn/advanced/geosearch.md +++ b/learn/advanced/geosearch.md @@ -121,7 +121,7 @@ In order to filter results based on their location, you must add the `_geo` attr Note that Meilisearch will rebuild your index whenever you update `filterableAttributes`. Depending on the size of your dataset, this might take a considerable amount of time. -[You can read more about configuring `filterableAttributes` in our dedicated filtering guide.](/learn/advanced/filtering_and_faceted_search.md#configuring-filters) +[You can read more about configuring `filterableAttributes` in our dedicated filtering guide.](/learn/advanced/filtering.md#configuring-filters) ### Usage @@ -135,7 +135,7 @@ _geoRadius(lat, lng, distance_in_meters) `lat` and `lng` must be floating point numbers indicating a geographic position. `distance_in_meters` must be an integer indicating the radius covered by the `_geoRadius` filter. If any of these three parameters are invalid or missing, Meilisearch will return an [`invalid_search_filter`](/reference/errors/error_codes.md#invalid-search-filter) error. -[You can read more about using `filter` in our dedicated guide.](/learn/advanced/filtering_and_faceted_search.md#using-filters) +[You can read more about using `filter` in our dedicated guide.](/learn/advanced/filtering.md#using-filters) ::: warning `_geo`, `_geoDistance`, and `_geoPoint` are not valid filter rules. Trying to use any of them with the `filter` search parameter will result in an [`invalid_search_filter`](/reference/errors/error_codes.md#invalid-search-filter) error. diff --git a/learn/advanced/indexing.md b/learn/advanced/indexing.md index b86ad160dc..06ec048e1e 100644 --- a/learn/advanced/indexing.md +++ b/learn/advanced/indexing.md @@ -1,6 +1,6 @@ # Indexing and performance -Adding new documents to an index is a multi-threaded and memory-intensive operation. Meilisearch's indexes are at the core of what makes our search engine fast, relevant and reliable. In this article, we will go over some of the details regarding RAM consumption and multi-threading. +Adding new documents to an index is a multi-threaded and memory-intensive operation. Meilisearch's indexes are at the core of what makes our search engine fast, relevant, and reliable. In this article, we will go over some of the details regarding RAM consumption and multi-threading. ## RAM @@ -10,7 +10,7 @@ It is important to prevent Meilisearch from using all available memory during in 1. Meilisearch may be killed by the OS for over-consuming RAM -2. Users making search requests may experience slowdown while the indexer is processing an update +2. Search performance may decrease while the indexer is processing an update Memory overconsumption can still happen in two cases: @@ -38,7 +38,7 @@ If you encounter performance issues during indexing, we recommend trying the fol - **Meilisearch should not be your main database**. The more documents you add, the longer will indexing and search take, so you should only index documents you want to retrieve when searching. -- By default, all document fields are searchable. We strongly recommend changing this by [updating the `searchableAttributes` list](/reference/api/settings.md#update-searchable-attributes) so it only contains fields you want to search in. The fewer fields Meilisearch needs to index, the faster is the indexing process. +- By default, all document fields are searchable. We strongly recommend changing this by [updating the `searchableAttributes` list](/reference/api/settings.md#update-searchable-attributes) so it only contains fields you want to search in. The fewer fields Meilisearch needs to index, the faster the indexing process. ```json [ @@ -57,13 +57,15 @@ If you encounter performance issues during indexing, we recommend trying the fol ] ``` +- If you have a multilingual dataset, create a separate index for each language. + - When creating a new index, first [configure its settings](/reference/api/settings.md) and only then add your documents. Following this order will significantly reduce indexing time. - Since indexing speed is tightly connected to the size of your payload, using lightweight dataset formats such as CSV and NDJSON can lead to increased performance. - Prefer machines using SSDs (Solid State Drives). We strongly recommend not running Meilisearch in HDDs (Hard Disk Drives). -- Ensure there are no limit to I/O operations in your machine. The restrictions imposed by cloud providers such as [AWS's Amazon EBS service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html#IOcredit) can severely impact indexing performance +- Ensure there is no limit to I/O operations in your machine. The restrictions imposed by cloud providers such as [AWS's Amazon EBS service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html#IOcredit) can severely impact indexing performance ## Memory crashes diff --git a/learn/core_concepts/documents.md b/learn/core_concepts/documents.md index 06e8797c94..1bec1710d5 100644 --- a/learn/core_concepts/documents.md +++ b/learn/core_concepts/documents.md @@ -38,6 +38,8 @@ You can modify this behavior using the [update settings endpoint](/reference/api In the latter case, the field will be completely ignored during search. However, it will still be [stored](/learn/configuration/displayed_searchable_attributes.md#data-storing) in the document. +To learn more, refer to our [displayed and searchable attributes guide](/learn/configuration/displayed_searchable_attributes.md). + ## Primary field The primary field is a special field that must be present in all documents. Its attribute is the [primary key](/learn/core_concepts/primary_key.md#primary-key-2) and its value is the [document id](/learn/core_concepts/primary_key.md#document-id). If you try to [index a document](/learn/getting_started/quick_start.md#add-documents) that's missing a primary key or possessing the wrong primary key for a given index, it will cause an error and no documents will be added. diff --git a/learn/core_concepts/indexes.md b/learn/core_concepts/indexes.md index fc95951eaf..a2ad6e08a8 100644 --- a/learn/core_concepts/indexes.md +++ b/learn/core_concepts/indexes.md @@ -101,7 +101,7 @@ Filtering allows you to refine your search based on different categories. For ex Before filtering on any document attribute, you must add it to `filterableAttributes` using the [update settings endpoint](/reference/api/settings.md#update-settings) or the [update filterable attributes endpoint](/reference/api/settings.md#update-filterable-attributes). Then, make a search query using the [`filter` search parameter](/reference/api/search.md#filter). -[Learn more about filtering.](/learn/advanced/filtering_and_faceted_search.md) +[Learn more about filtering.](/learn/advanced/filtering.md) ### Pagination diff --git a/learn/getting_started/customizing_relevancy.md b/learn/getting_started/customizing_relevancy.md index e98543bbbe..819795808a 100644 --- a/learn/getting_started/customizing_relevancy.md +++ b/learn/getting_started/customizing_relevancy.md @@ -161,7 +161,7 @@ Suppose your results contain the following values for the `genres` facet: `Actio -You can read more about faceting in our [dedicated guide](/learn/advanced/filtering_and_faceted_search.md). +You can read more about faceting in our [dedicated guide](/learn/advanced/faceted_search.md). ## Pagination diff --git a/learn/getting_started/filtering_and_sorting.md b/learn/getting_started/filtering_and_sorting.md index 5c76408e8c..ad56aa735b 100644 --- a/learn/getting_started/filtering_and_sorting.md +++ b/learn/getting_started/filtering_and_sorting.md @@ -51,7 +51,7 @@ Let's say you only want to view meteorites that weigh less than 200g: Filtering is intended to be combined with search queries to refine your results. -To learn more about filters and how to configure them, refer to our [dedicated guide](/learn/advanced/filtering_and_faceted_search.md). +To learn more about filters and how to configure them, refer to our [dedicated guide](/learn/advanced/filtering.md). ## Sorting diff --git a/learn/getting_started/installation.md b/learn/getting_started/installation.md index 80a1b03583..fb5f666cf8 100644 --- a/learn/getting_started/installation.md +++ b/learn/getting_started/installation.md @@ -51,6 +51,7 @@ docker run -it --rm \ -e MEILI_ENV='development' \ -v $(pwd)/meili_data:/meili_data \ getmeili/meilisearch:v1.0 +# Use ${pwd} instead of $(pwd) in PowerShell ``` You can learn more about [using Meilisearch with Docker in our dedicated guide](/learn/cookbooks/docker.md). diff --git a/learn/getting_started/quick_start.md b/learn/getting_started/quick_start.md index 59c448fd22..4dd545d97a 100644 --- a/learn/getting_started/quick_start.md +++ b/learn/getting_started/quick_start.md @@ -23,6 +23,10 @@ curl -L https://install.meilisearch.com | sh You have the option to install Meilisearch locally or deploy it over a cloud service. Learn more about the other installation options in our [installation guide](/learn/getting_started/installation.md). +::: note +If you started Meilisearch with a master key or using Meilisearch Cloud, you will need to add the [`-H Authorization: Bearer API_KEY` header](/reference/api/overview.md#authorization) to all your curl commands. +::: + ### Running Meilisearch On successfully running Meilisearch, you should see the following response: @@ -141,6 +145,8 @@ In the above code sample, the parameter `q` represents the search query. The doc By default, Meilisearch only returns the first 20 results for a search query. This can be changed using the [`limit` parameter](/reference/api/search.md#limit). +To search on multiple indexes at the same time with a single request, use the [`/multi-search` endpoint.](/reference/api/multi_search.md) + ## Search preview Meilisearch offers a browser-based search preview where you can search through a selected index. You can access it any time Meilisearch is running at `http://localhost:7700`. diff --git a/learn/what_is_meilisearch/comparison_to_alternatives.md b/learn/what_is_meilisearch/comparison_to_alternatives.md index 3ccd3c4b6e..afcdd752c1 100644 --- a/learn/what_is_meilisearch/comparison_to_alternatives.md +++ b/learn/what_is_meilisearch/comparison_to_alternatives.md @@ -95,7 +95,7 @@ Can't find a client you'd like us to support? [Submit your idea or vote for it]( | | Meilisearch | Algolia | Typesense | Elasticsearch | |---|:---:|:----:|:---:|:---:| | Placeholder search | ✅ | ✅ | ✅ | ✅ | -| Multi-index search | [2023](https://github.com/meilisearch/product/issues/74) | ✅ | ✅ | ✅ | +| Multi-index search (federated search) | ✅ | ✅ | ✅ | ✅ | | Exact phrase search | ✅ | ✅ | ✅ | ✅ | | Geo search | ✅ | ✅ | ✅ | ✅ | | Sort by | ✅ | 🔶
Limited to one `sort_by` rule per index. Indexes may have to be duplicated for each sort field and sort order | ✅
Up to 3 sort fields per search query | ✅ | diff --git a/learn/what_is_meilisearch/features.md b/learn/what_is_meilisearch/features.md index b042068e92..08c7e648d8 100644 --- a/learn/what_is_meilisearch/features.md +++ b/learn/what_is_meilisearch/features.md @@ -34,7 +34,7 @@ Search in the real world. [Geosearch](/learn/advanced/geosearch.md), also known ## Filtering -Create [filters](/learn/advanced/filtering_and_faceted_search.md) to refine results based on user-defined criteria. +Create [filters](/learn/advanced/filtering.md) to refine results based on user-defined criteria. ## Faceting @@ -63,3 +63,7 @@ Use [index swapping](/learn/core_concepts/indexes.md#swapping-indexes) to deploy ## Phrase search [Wrap search terms in double quotes (`"`) for strict queries](/reference/api/search.md#phrase-search) that only return exact matches. + +## Multi-index search + +Also known as federated search, it allows you to perform [search queries on multiple indexes with a single HTTP request](/reference/api/multi_search.md). diff --git a/learn/what_is_meilisearch/language.md b/learn/what_is_meilisearch/language.md index b034e40de2..a6f826bc26 100644 --- a/learn/what_is_meilisearch/language.md +++ b/learn/what_is_meilisearch/language.md @@ -17,7 +17,7 @@ We aim to provide global language support, and your feedback helps us move close While we have employees from all over the world at Meilisearch, we don't speak every language. We rely almost entirely on feedback from external contributors to understand how our engine is performing across different languages. -If you'd like to request optimized support for a language, please upvote the related [discussion in our product repository](https://github.com/meilisearch/product/discussions?discussions_q=label%3Aproduct%3Acore%3Atokenizer) or [open a new one](https://github.com/meilisearch/product/discussions/new?category=feedback-feature-proposal) if it doesn't exist. +If you'd like to request optimized support for a language, please upvote the related [discussion in our product repository](https://github.com/meilisearch/product/discussions?discussions_q=label%3Ascope%3Atokenizer+) or [open a new one](https://github.com/meilisearch/product/discussions/new?category=feedback-feature-proposal) if it doesn't exist. If you'd like to help by developing a tokenizer pipeline yourself: first of all, thank you! We recommend that you take a look at the [tokenizer contribution guide](https://github.com/meilisearch/charabia/blob/main/CONTRIBUTING.md) before making a PR. @@ -25,13 +25,7 @@ If you'd like to help by developing a tokenizer pipeline yourself: first of all, ### What do you mean when you say Meilisearch offers _optimized_ support for a language? -Under the hood, Meilisearch relies on tokenizers that identify the most important parts of each document in a given dataset. We currently use five tokenization pipelines: - -- A default pipeline designed for languages that separate words with spaces -- A pipeline specifically tailored for Chinese -- A pipeline specifically tailored for Hebrew -- A pipeline specifically tailored for Japanese -- A pipeline specifically tailored for Thai +Optimized support for a language means Meilisearch has implemented internal processes specifically tailored to parsing that language, leading to more relevant results. ### My language does not use whitespace to separate words. Can I still use Meilisearch? @@ -43,4 +37,4 @@ Yes—our users work with many different alphabets and writing systems, such as ### Does Meilisearch plan to support additional languages in the future? -Yes, we definitely do. The more [feedback](https://github.com/meilisearch/product/discussions?discussions_q=label%3Aproduct%3Acore%3Atokenizer) we get from native speakers, the easier it is for us to understand how to improve performance for those languages. Similarly, the more requests we get to improve support for a specific language, the more likely we are to devote resources to that project. +Yes, we definitely do. The more feedback we get from native speakers, the easier it is for us to understand how to improve performance for those languages. Similarly, the more requests we get to improve support for a specific language, the more likely we are to devote resources to that project. diff --git a/learn/what_is_meilisearch/philosophy.md b/learn/what_is_meilisearch/philosophy.md index 31c4d801d4..d0457a824a 100644 --- a/learn/what_is_meilisearch/philosophy.md +++ b/learn/what_is_meilisearch/philosophy.md @@ -18,7 +18,7 @@ It wouldn't be a search engine if there wasn't a notion of relevancy in the resu The returned results are **sorted according to a set of consecutive rules called [ranking rules](/learn/core_concepts/relevancy.md#ranking-rules)**. You can delete existing rules, add new ones, or even change the order in which they are executed. -You can also **configure the [search parameters](/reference/api/search.md)** to refine your search even further. We support [filters](/learn/advanced/filtering_and_faceted_search.md) and [faceting](/learn/advanced/filtering_and_faceted_search.md#faceted-search). +You can also **configure the [search parameters](/reference/api/search.md)** to refine your search even further. We support [filters](/learn/advanced/filtering.md) and [faceting](/learn/advanced/faceted_search.md#faceted-search). ### Front-facing search diff --git a/reference/api/multi_search.md b/reference/api/multi_search.md new file mode 100644 index 0000000000..8bf9015074 --- /dev/null +++ b/reference/api/multi_search.md @@ -0,0 +1,122 @@ +# Multi-index search + +The `/multi-search` route allows you to perform multiple search queries on one or more indexes by bundling them into a single HTTP request. Multi-index search is also known as federated search. + +## POST route + + + +### Body + +| Name | Type | Description | +| :------------ | :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | +| **`queries`** | Array of objects | Contains the list of search queries to perform. The [`indexUid`](#search-parameters) search parameter is required, all other parameters are optional | + +#### Search parameters + +| Search parameter | Type | Default value | Description | +| :------------------------------------------------------------------------------ | :--------------- | :------------ | :-------------------------------------------------- | +| **[`indexUid`](/learn/core_concepts/indexes.md#index-uid)** | String | N/A | `uid` of the requested index | +| **[`q`](/reference/api/search.md#query-q)** | String | `""` | Query string | +| **[`offset`](/reference/api/search.md#offset)** | Integer | `0` | Number of documents to skip | +| **[`limit`](/reference/api/search.md#limit)** | Integer | `20` | Maximum number of documents returned | +| **[`hitsPerPage`](/reference/api/search.md#number-of-results-per-page)** | Integer | `1` | Maximum number of documents returned for a page | +| **[`page`](/reference/api/search.md#page)** | Integer | `1` | Request a specific page of results | +| **[`filter`](/reference/api/search.md#filter)** | Array of strings | `null` | Filter queries by an attribute's value | +| **[`facets`](/reference/api/search.md#facets)** | Array of strings | `null` | Display the count of matches per facet | +| **[`attributesToRetrieve`](/reference/api/search.md#attributes-to-retrieve)** | Array of strings | `["*"]` | Attributes to display in the returned documents | +| **[`attributesToCrop`](/reference/api/search.md#attributes-to-crop)** | Array of strings | `null` | Attributes whose values have to be cropped | +| **[`cropLength`](/reference/api/search.md#crop-length)** | Integer | `10` | Maximum length of cropped value in words | +| **[`cropMarker`](/reference/api/search.md#crop-marker)** | String | `"…"` | String marking crop boundaries | +| **[`attributesToHighlight`](/reference/api/search.md#attributes-to-highlight)** | Array of strings | `null` | Highlight matching terms contained in an attribute | +| **[`highlightPreTag`](/reference/api/search.md#highlight-tags)** | String | `""` | String inserted at the start of a highlighted term | +| **[`highlightPostTag`](/reference/api/search.md#highlight-tags)** | String | `""` | String inserted at the end of a highlighted term | +| **[`showMatchesPosition`](/reference/api/search.md#show-matches-position)** | Boolean | `false` | Return matching terms location | +| **[`sort`](/reference/api/search.md#sort)** | Array of strings | `null` | Sort search results by an attribute's value | +| **[`matchingStrategy`](/reference/api/search.md#matching-strategy)** | String | `last` | Strategy used to match query terms within documents | + +[Learn more about how to use each search parameter](/reference/api/search.md#search-parameters). + +### Response + +| Name | Type | Description | +| :------------ | :--------------- | :--------------------------------------------------------------------- | +| **`results`** | Array of objects | Results of the search queries in the same order they were requested in | + +Each search result object is composed of the following fields: + +| Name | Type | Description | +| :----------------------- | :--------------- | :-------------------------------------------------------------------------------------- | +| **`indexUid`** | String | [`uid`](/learn/core_concepts/indexes.md#index-uid) of the requested index | +| **`hits`** | Array of objects | Results of the query | +| **`offset`** | Number | Number of documents skipped | +| **`limit`** | Number | Number of documents to take | +| **`estimatedTotalHits`** | Number | Estimated total number of matches | +| **`totalHits`** | Number | Exhaustive total number of matches | +| **`totalPages`** | Number | Exhaustive total number of search result pages | +| **`hitsPerPage`** | Number | Number of results on each page | +| **`page`** | Number | Current search results page | +| **`facetDistribution`** | Object | **[Distribution of the given facets](/reference/api/search.md#facetdistribution)** | +| **`facetStats`** | Object | [The the numeric `min` and `max` values per facet](/reference/api/search.md#facetstats) | +| **`processingTimeMs`** | Number | Processing time of the query | +| **`query`** | String | Query originating the response | + +### Example + + + +#### Response: `200 Ok` + +```json +{ + "results":[ + { + "indexUid":"movies", + "hits":[ + { + "id":13682, + "title":"Pooh's Heffalump Movie", + … + }, + … + ], + "query":"pooh", + "processingTimeMs":26, + "limit":5, + "offset":0, + "estimatedTotalHits":22 + }, + { + "indexUid":"movies", + "hits":[ + { + "id":12, + "title":"Finding Nemo", + … + }, + … + ], + "query":"nemo", + "processingTimeMs":5, + "limit":5, + "offset":0, + "estimatedTotalHits":11 + }, + { + "indexUid":"movie_ratings", + "hits":[ + { + "id":"Us", + "director": "Jordan Peele", + … + } + ], + "query":"Us", + "processingTimeMs":0, + "limit":20, + "offset":0, + "estimatedTotalHits":1 + } + ] +} +``` diff --git a/reference/api/search.md b/reference/api/search.md index 23e8f48990..a9bd359ef0 100644 --- a/reference/api/search.md +++ b/reference/api/search.md @@ -67,19 +67,20 @@ Query terms enclosed in double quotes are treated as [phrase searches](#query-q) ### Response -| Name | Type | Description | -| :----------------------- | :--------------- | :---------------------------------------------- | -| **`hits`** | Array of objects | Results of the query | -| **`offset`** | Number | Number of documents skipped | -| **`limit`** | Number | Number of documents to take | -| **`estimatedTotalHits`** | Number | Estimated total number of matches | -| **`totalHits`** | Number | Exhaustive total number of matches | -| **`totalPages`** | Number | Exhaustive total number of search result pages | -| **`hitsPerPage`** | Number | Number of results on each page | -| **`page`** | Number | Current search results page | -| **`facetDistribution`** | Object | **[Distribution of the given facets](#facets)** | -| **`processingTimeMs`** | Number | Processing time of the query | -| **`query`** | String | Query originating the response | +| Name | Type | Description | +| :----------------------- | :--------------- | :---------------------------------------------------------- | +| **`hits`** | Array of objects | Results of the query | +| **`offset`** | Number | Number of documents skipped | +| **`limit`** | Number | Number of documents to take | +| **`estimatedTotalHits`** | Number | Estimated total number of matches | +| **`totalHits`** | Number | Exhaustive total number of matches | +| **`totalPages`** | Number | Exhaustive total number of search result pages | +| **`hitsPerPage`** | Number | Number of results on each page | +| **`page`** | Number | Current search results page | +| **`facetDistribution`** | Object | **[Distribution of the given facets](#facetdistribution)** | +| **`facetStats`** | Object | [The numeric `min` and `max` values per facet](#facetstats) | +| **`processingTimeMs`** | Number | Processing time of the query | +| **`query`** | String | Query originating the response | #### Exhaustive and estimated total number of search results @@ -131,7 +132,7 @@ You can [read more about pagination in our dedicated guide](/learn/advanced/pagi Search for documents matching a specific query in the given index. ::: warning -This endpoint only accepts [string filter expressions](/learn/advanced/filtering_and_faceted_search.md#filter-expressions). +This endpoint only accepts [string filter expressions](/learn/advanced/filtering.md#filter-expressions). ::: This endpoint should only be used when no API key is required. If an API key is required, use the [POST](/reference/api/search.md#search-in-an-index-with-post-route) route instead. @@ -180,19 +181,20 @@ Query terms enclosed in double quotes are treated as [phrase searches](#query-q) ### Response -| Name | Type | Description | -| :----------------------- | :--------------- | :---------------------------------------------- | -| **`hits`** | Array of objects | Results of the query | -| **`offset`** | Number | Number of documents skipped | -| **`limit`** | Number | Number of documents to take | -| **`totalHits`** | Number | Exhaustive total number of matches | -| **`totalPages`** | Number | Exhaustive total number of search results pages | -| **`hitsPerPage`** | Number | Number of results on each page | -| **`page`** | Number | Current search results page | -| **`estimatedTotalHits`** | Number | Total number of matches | -| **`facets`** | Object | **[Distribution of the given facets](#facets)** | -| **`processingTimeMs`** | Number | Processing time of the query | -| **`query`** | String | Query originating the response | +| Name | Type | Description | +| :----------------------- | :--------------- | :---------------------------------------------------------- | +| **`hits`** | Array of objects | Results of the query | +| **`offset`** | Number | Number of documents skipped | +| **`limit`** | Number | Number of documents to take | +| **`totalHits`** | Number | Exhaustive total number of matches | +| **`totalPages`** | Number | Exhaustive total number of search results pages | +| **`hitsPerPage`** | Number | Number of results on each page | +| **`page`** | Number | Current search results page | +| **`estimatedTotalHits`** | Number | Total number of matches | +| **`facets`** | Object | **[Distribution of the given facets](#facetdistribution)** | +| **`facetStats`** | Object | [The numeric `min` and `max` values per facet](#facetstats) | +| **`processingTimeMs`** | Number | Processing time of the query | +| **`query`** | String | Query originating the response | ### Example @@ -229,7 +231,7 @@ Query terms enclosed in double quotes are treated as [phrase searches](#query-q) ## Search parameters -Here follows an exhaustive description of each search parameter currently available when using the search endpoint. Unless otherwise noted, all parameters are valid for both `GET` and `POST` routes. +Here follows an exhaustive description of each search parameter currently available when using the search endpoint. Unless otherwise noted, all parameters are valid for the `GET /indexes/{index_uid}/search`, `POST /indexes/{index_uid}/search`, and `/multi-search` routes. ::: warning If [using the `GET` route to perform a search](/reference/api/search.md#search-in-an-index-with-get-route), all parameters must be **URL-encoded**. @@ -312,7 +314,7 @@ When `q` isn't specified, Meilisearch performs a **placeholder search**. A plac If the index has no sort or custom ranking rules, the results are returned in the order of their internal database position. ::: tip -Placeholder search is particularly useful when building a [faceted search interfaces](/learn/advanced/filtering_and_faceted_search.md#faceted-search), as it allows users to view the catalog and alter sorting rules without entering a query. +Placeholder search is particularly useful when building a [faceted search interfaces](/learn/advanced/faceted_search.md#faceted-search), as it allows users to view the catalog and alter sorting rules without entering a query. ::: #### Phrase search @@ -433,7 +435,7 @@ The following example returns the second page of search results: Uses filter expressions to refine search results. Attributes used as filter criteria must be added to the [`filterableAttributes` list](/reference/api/settings.md#filterable-attributes). -For more information on how to use filters and build filter expressions, [read our guide on filtering, faceted search, and filter expressions](/learn/advanced/filtering_and_faceted_search.md). +For more information on how to use filters and build filter expressions, [read our guide on filtering and filter expressions](/learn/advanced/filtering.md). #### Example diff --git a/reference/api/settings.md b/reference/api/settings.md index 33c539d150..713543201e 100644 --- a/reference/api/settings.md +++ b/reference/api/settings.md @@ -531,7 +531,7 @@ Attributes in the `filterableAttributes` list can be used as filters or facets. Updating filterable attributes will re-index all documents in the index, which can take some time. We recommend updating your index settings first and then adding documents as this reduces RAM consumption. ::: -[To learn more about filterable attributes, refer to our dedicated guide.](/learn/advanced/filtering_and_faceted_search.md) +[To learn more about filterable attributes, refer to our dedicated guide.](/learn/advanced/filtering.md) ### Get filterable attributes @@ -585,7 +585,7 @@ If an attribute contains an object, you can use dot notation to set one or more If the field does not exist, no error will be thrown. ::: -[To learn more about filterable attributes, refer to our dedicated guide.](/learn/advanced/filtering_and_faceted_search.md) +[To learn more about filterable attributes, refer to our dedicated guide.](/learn/advanced/filtering.md) #### Example