Skip to content

Commit d2cb2a4

Browse files
committed
Merge branch 'pensu-feature-descriptions' into feature-descriptions
2 parents 054aea1 + 4c61dc7 commit d2cb2a4

File tree

6 files changed

+546
-1
lines changed

6 files changed

+546
-1
lines changed

docs-site/content/.vuepress/config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const { description } = require('../../package')
22
const { typesenseVersions, typesenseLatestVersion } = require('../../../typsenseVersions')
3+
const path = require('path')
34

45
let config = {
56
// The base URL the site will be deployed at
@@ -696,7 +697,7 @@ let config = {
696697
configureWebpack: {
697698
resolve: {
698699
alias: {
699-
'@images': '../../.vuepress/public/images'
700+
'@images': path.resolve(__dirname, 'public/images/')
700701
}
701702
}
702703
}
170 KB
Loading
214 KB
Loading
Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,340 @@
11
# Faceting
2+
3+
Faceting is a way to classify search results into smaller groups based on the attributes in each result. For example, in a dataset of books, after users search for a book title, they'd want to categorize the search results by authors, genre, etc. Similarly, in a movie dataset, users may want to search for movies by first grouping them via actor, director, genre, etc. This subclassification of search results is known as Faceting. Faceting is not to be confused with Filtering, as Filtering provides a way to remove results that don't meet certain criteria, while Faceting provides a way to group results into categories.
4+
5+
In a UI based system, facets can be used to show options to users to help them further refine search results. For example, in our [Book Search Showcase](https://books-search.typesense.org/), if you search for an author, you'll see fields in the left panel giving users the option to further refine their search results by subject or author. It also shows the count for the facet fields. In the image below, you can see that the `Fiction` facet has 408 docuemnts, while `Classics` facet has 363 documents. We were able to categorize and count all the authors and subjects in the result set, by setting authors and subject as facet fields.
6+
7+
![Typesense facet example](~@images/typesense-facet.png)
8+
9+
Typesense provides out-of-the-box support for Faceting. To facet results, you first need to define one or more facet fields. This field will allow Typesense to subgroup results into categories and then the search results can be refined in that subgroup. In a book dataset, you can define a facet field on authors or publication year:
10+
11+
<Tabs :tabs="['JavaScript','PHP','Python','Ruby']">
12+
<template v-slot:JavaScript>
13+
14+
```javascript
15+
booksSchema = {
16+
'name': 'books',
17+
'fields': [
18+
{'name': 'title', 'type': 'string' },
19+
{'name': 'authors', 'type': 'string[]' },
20+
{'name': 'image_url', 'type': 'string' },
21+
22+
{'name': 'publication_year', 'type': 'int32' },
23+
{'name': 'ratings_count', 'type': 'int32' },
24+
{'name': 'average_rating', 'type': 'float' },
25+
26+
{'name': 'authors_facet', 'type': 'string[]', 'facet': true },
27+
{'name': 'publication_year_facet', 'type': 'string', 'facet': true },
28+
],
29+
'default_sorting_field': 'ratings_count'
30+
}
31+
32+
```
33+
</template>
34+
35+
<template v-slot:PHP>
36+
37+
```php
38+
$booksSchema = [
39+
'name' => 'books',
40+
'fields' => [
41+
['name' => 'title', 'type' => 'string'],
42+
['name' => 'authors', 'type' => 'string[]'],
43+
['name' => 'image_url', 'type' => 'string'],
44+
45+
['name' => 'publication_year', 'type' => 'int32'],
46+
['name' => 'ratings_count', 'type' => 'int32'],
47+
['name' => 'average_rating', 'type' => 'float'],
48+
49+
['name' => 'authors_facet', 'type' => 'string[]', 'facet' => true],
50+
['name' => 'publication_year_facet', 'type' => 'string', 'facet' => true]
51+
],
52+
'default_sorting_field' => 'ratings_count'
53+
];
54+
55+
```
56+
</template>
57+
<template v-slot:Python>
58+
59+
```python
60+
books_schema = {
61+
'name': 'books',
62+
'fields': [
63+
{'name': 'title', 'type': 'string' },
64+
{'name': 'authors', 'type': 'string[]' },
65+
{'name': 'image_url', 'type': 'string' },
66+
67+
{'name': 'publication_year', 'type': 'int32' },
68+
{'name': 'ratings_count', 'type': 'int32' },
69+
{'name': 'average_rating', 'type': 'float' },
70+
71+
{'name': 'authors_facet', 'type': 'string[]', 'facet': True },
72+
{'name': 'publication_year_facet', 'type': 'string', 'facet': True },
73+
],
74+
'default_sorting_field': 'ratings_count'
75+
}
76+
77+
```
78+
</template>
79+
<template v-slot:Ruby>
80+
81+
```ruby
82+
books_schema = {
83+
'name' => 'books',
84+
'fields' => [
85+
{'name' => 'title', 'type' => 'string' },
86+
{'name' => 'authors', 'type' => 'string[]' },
87+
{'name' => 'image_url', 'type' => 'string' },
88+
89+
{'name' => 'publication_year', 'type' => 'int32' },
90+
{'name' => 'ratings_count', 'type' => 'int32' },
91+
{'name' => 'average_rating', 'type' => 'float' },
92+
93+
{'name' => 'authors_facet', 'type' => 'string[]', 'facet' => true },
94+
{'name' => 'publication_year_facet', 'type' => 'string', 'facet' => true }
95+
],
96+
'default_sorting_field' => 'ratings_count'
97+
}
98+
```
99+
</template>
100+
</Tabs>
101+
102+
In above example, `authors_facet` and `publication_year_facet` are facet fields. Let's see the faceted search in action!
103+
104+
<Tabs :tabs="['JavaScript','PHP','Python','Ruby']">
105+
<template v-slot:JavaScript>
106+
107+
```javascript
108+
let searchParameters = {
109+
'q' : 'experiment',
110+
'query_by' : 'title',
111+
'facet_by' : 'authors_facet',
112+
'sort_by' : 'average_rating:desc'
113+
}
114+
115+
client.collections('books')
116+
.documents()
117+
.search(searchParameters)
118+
.then(function (searchResults) {
119+
console.log(searchResults)
120+
})
121+
```
122+
</template>
123+
124+
<template v-slot:PHP>
125+
126+
```php
127+
$searchParameters = [
128+
'q' => 'experiment',
129+
'query_by' => 'title',
130+
'facet_by' => 'authors_facet',
131+
'sort_by' => 'average_rating:desc'
132+
];
133+
134+
$client->collections['books']->documents->search($searchParameters);
135+
```
136+
</template>
137+
<template v-slot:Python>
138+
139+
```python
140+
search_parameters = {
141+
'q' : 'experiment',
142+
'query_by' : 'title',
143+
'facet_by' : 'authors_facet',
144+
'sort_by' : 'average_rating:desc'
145+
}
146+
147+
client.collections['books'].documents.search(search_parameters)
148+
```
149+
</template>
150+
<template v-slot:Ruby>
151+
152+
```ruby
153+
search_parameters = {
154+
'q' => 'experiment',
155+
'query_by' => 'title',
156+
'facet_by' => 'authors_facet',
157+
'sort_by' => 'average_rating:desc'
158+
}
159+
160+
client.collections['books'].documents.search(search_parameters)
161+
```
162+
</template>
163+
</Tabs>
164+
165+
The `facet_by` parameter provides the results grouped by authors. Here is a sample response:
166+
167+
```json
168+
{
169+
"facet_counts": [
170+
{
171+
"field_name": "authors_facet",
172+
"counts": [
173+
{
174+
"count": 2,
175+
"value": " Käthe Mazur"
176+
},
177+
{
178+
"count": 2,
179+
"value": "Gretchen Rubin"
180+
},
181+
{
182+
"count": 2,
183+
"value": "James Patterson"
184+
},
185+
{
186+
"count": 2,
187+
"value": "Mahatma Gandhi"
188+
}
189+
]
190+
}
191+
],
192+
"found": 3,
193+
"hits": [
194+
{
195+
"_highlight": {
196+
"title": "The Angel <mark>Experiment</mark>"
197+
},
198+
"document": {
199+
"authors": [
200+
"James Patterson"
201+
],
202+
"authors_facet": [
203+
"James Patterson"
204+
],
205+
"average_rating": 4.08,
206+
"id": "569",
207+
"image_url": "https://images.gr-assets.com/books/1339277875m/13152.jpg",
208+
"publication_year": 2005,
209+
"publication_year_facet": "2005",
210+
"ratings_count": 172302,
211+
"title": "The Angel Experiment"
212+
}
213+
},
214+
...
215+
]
216+
}
217+
```
218+
219+
As you see in the response, by using `facet_by` Typesense can group the results by authors and show you counts of how many of the books in the result set were written by each author. If you facet by an integer field, the result will also show avg, mix, max and sum value of that field in addition to `count`. Let's try that by faceting the search by `ratings_count`. Before running the below search query, make sure that `ratings_count` is a facet field.
220+
221+
<Tabs :tabs="['JavaScript','PHP','Python','Ruby']">
222+
<template v-slot:JavaScript>
223+
224+
```javascript
225+
let searchParameters = {
226+
'q' : 'experiment',
227+
'query_by' : 'title',
228+
'facet_by' : 'ratings_count',
229+
'sort_by' : 'average_rating:desc'
230+
}
231+
232+
client.collections('books')
233+
.documents()
234+
.search(searchParameters)
235+
.then(function (searchResults) {
236+
console.log(searchResults)
237+
})
238+
```
239+
</template>
240+
241+
<template v-slot:PHP>
242+
243+
```php
244+
$searchParameters = [
245+
'q' => 'experiment',
246+
'query_by' => 'title',
247+
'facet_by' => 'ratings_count',
248+
'sort_by' => 'average_rating:desc'
249+
]
250+
251+
$client->collections['books']->documents->search($searchParameters)
252+
```
253+
</template>
254+
<template v-slot:Python>
255+
256+
```python
257+
search_parameters = {
258+
'q' : 'experiment',
259+
'query_by' : 'title',
260+
'facet_by' : 'ratings_count',
261+
'sort_by' : 'average_rating:desc'
262+
}
263+
264+
client.collections['books'].documents.search(search_parameters)
265+
```
266+
</template>
267+
<template v-slot:Ruby>
268+
269+
```ruby
270+
search_parameters = {
271+
'q' => 'experiment',
272+
'query_by' => 'title',
273+
'facet_by' => 'ratings_count',
274+
'sort_by' => 'average_rating:desc'
275+
}
276+
277+
client.collections['books'].documents.search(search_parameters)
278+
```
279+
</template>
280+
</Tabs>
281+
282+
Sample response:
283+
284+
```json
285+
{
286+
"facet_counts": [
287+
{
288+
"counts": [
289+
{
290+
"count": 1,
291+
"highlighted": "6058",
292+
"value": "6058"
293+
},
294+
{
295+
"count": 1,
296+
"highlighted": "28177",
297+
"value": "28177"
298+
},
299+
{
300+
"count": 1,
301+
"highlighted": "172302",
302+
"value": "172302"
303+
}
304+
],
305+
"field_name": "ratings_count",
306+
"stats": {
307+
"avg": 68845.66666666667,
308+
"max": 172302.0,
309+
"min": 6058.0,
310+
"sum": 206537.0
311+
}
312+
}
313+
],
314+
"found": 3,
315+
"hits": [
316+
{
317+
"document": {
318+
"authors": [
319+
"James Patterson"
320+
],
321+
"authors_facet": [
322+
"James Patterson"
323+
],
324+
"average_rating": 4.08,
325+
"id": "569",
326+
"image_url": "https://images.gr-assets.com/books/1339277875m/13152.jpg",
327+
"publication_year": 2005,
328+
"publication_year_facet": "2005",
329+
"ratings_count": 172302,
330+
"title": "The Angel Experiment"
331+
},
332+
}
333+
...
334+
]
335+
}
336+
```
337+
338+
Note the additional `stats` field in the result that shows the avg, min, max and sum value for `ratings_count` field. You can limit the number of faceted results using `max_facet_value` parameter. More details on these arguments can be found [here](../../api/documents.html#arguments).
339+
340+
In summary, we use facets to group results into categories and present them to users. Then users can pick one of those categories as a [filter](./filtering.md).

0 commit comments

Comments
 (0)