From edf0a0042934420ef8dba1c0f653b7f119106057 Mon Sep 17 00:00:00 2001 From: Philip Krauss <35487337+philkra@users.noreply.github.com> Date: Wed, 6 Dec 2023 09:28:27 +0100 Subject: [PATCH] Golang SDK (#166) * Init Golang SDK * search table * examples contrinued * delete snippets * Add python sdk schema edit references (#167) * add python sdk schema edit references * Update 040-SDK/020-Python/020-examples.mdx Co-authored-by: Philip Krauss <35487337+philkra@users.noreply.github.com> * Update 040-SDK/020-Python/020-examples.mdx Co-authored-by: Philip Krauss <35487337+philkra@users.noreply.github.com> * Update 040-SDK/020-Python/020-examples.mdx Co-authored-by: Philip Krauss <35487337+philkra@users.noreply.github.com> * Update 040-SDK/020-Python/020-examples.mdx Co-authored-by: Philip Krauss <35487337+philkra@users.noreply.github.com> * Update 040-SDK/020-Python/020-examples.mdx Co-authored-by: Philip Krauss <35487337+philkra@users.noreply.github.com> * Update 020-examples.mdx --------- Co-authored-by: Philip Krauss <35487337+philkra@users.noreply.github.com> * Point GH actions to FE (#168) * fix missing commas (#169) * Fix pricing docs URL (#170) rate limiting URL was pointing to an old docs page. * add updates for api docs (#165) * add updates for api docs * rewording * Update 060-Rest-API/010-authentication.mdx Co-authored-by: Kostas Botsas * Update 060-Rest-API/020-contexts.mdx Co-authored-by: Kostas Botsas * Update 010-authentication.mdx * links * update lint * update heading * update heading --------- Co-authored-by: Kostas Botsas * Vercel deploys via github action (#173) * clarify Postman Bearer Token (#175) * clarify Postman Bearer Token * Update 060-Rest-API/020-contexts.mdx Co-authored-by: joan-ing * reword * Update preview.yml * Update preview.yml --------- Co-authored-by: joan-ing Co-authored-by: Alexis Rico * Update sparse-checkout in workflows (#176) * Clarify main branch in Workflow (#178) * Clarify main used in Workflow * Update 040-workflow.mdx reword * Update 040-workflow.mdx reword 2 * Update docs for search change (#177) Signed-off-by: Alexis Rico * more create examples * replace tabs with spaces * align var names * fix bulk insert example * one more * linting * update samples * one more update example * vector search examples * ask samples * trx snippet * update numeric ops * overview page * change alert to warning * Update 040-SDK/030-Go/010-overview.mdx Co-authored-by: joan-ing * Update 040-SDK/030-Go/010-overview.mdx Co-authored-by: joan-ing * Update 020-Getting-started/040-workflow.mdx Co-authored-by: joan-ing * Update 020-Getting-started/040-workflow.mdx Co-authored-by: joan-ing * Update 020-Getting-started/040-workflow.mdx Co-authored-by: joan-ing * Update 040-SDK/020-Python/020-examples.mdx Co-authored-by: joan-ing * add search items * Update 040-SDK/030-Go/010-overview.mdx Co-authored-by: joan-ing * make linter happy * Update 040-SDK/030-Go/010-overview.mdx Co-authored-by: joan-ing * Apply suggestions from code review Co-authored-by: joan-ing * indent * add search skel * indent * add response struct * linter * Apply suggestions from code review Co-authored-by: joan-ing * add install --------- Signed-off-by: Alexis Rico Co-authored-by: Kostas Botsas Co-authored-by: Dave Snider Co-authored-by: joan-ing Co-authored-by: Richard Gill Co-authored-by: Alexis Rico --- 020-Getting-started/040-workflow.mdx | 6 +- 040-SDK/020-Python/020-examples.mdx | 2 +- 040-SDK/030-Go/010-overview.mdx | 75 ++++++++ 040-SDK/101-get.mdx | 155 +++++++++++++---- 040-SDK/102-create.mdx | 75 +++++++- 040-SDK/103-update.mdx | 107 +++++++++++- 040-SDK/104-delete.mdx | 34 +++- 040-SDK/111-search.mdx | 61 ++++++- 040-SDK/111-vector-search.mdx | 30 +++- 040-SDK/130-transaction.mdx | 108 +++++++++--- 040-SDK/140-ask.mdx | 246 +++++++++++++++++++++------ 11 files changed, 770 insertions(+), 129 deletions(-) create mode 100644 040-SDK/030-Go/010-overview.mdx diff --git a/020-Getting-started/040-workflow.mdx b/020-Getting-started/040-workflow.mdx index c41de9e7..85738649 100644 --- a/020-Getting-started/040-workflow.mdx +++ b/020-Getting-started/040-workflow.mdx @@ -162,11 +162,11 @@ xata pull my_feature On completion, notice Xata updated our client files in `src/xata.ts` and added migration files in the `.xata/migrations` folder. The later files are needed for GitHub to pick up on the changes we've made. Each time you make changes to your database branch, you will need to run `xata pull my_feature`. -### Commit your code, and create a GitHub PR +### Commit code and create a pull request -Once you are happy with your changes you should commit your files and create a GitHub PR for your Git branch. Xata's GitHub application will look for new files in your `.xata/migrations` folder so make sure they are included in the commit. Regardless of whether migrations are present, Xata will generate a preview branch for any PR you deploy using a `preview-{branch_name}` naming system. This is done by forking the `main` branch, applying schema migrations from the Pull Request branch and copying over sample data from `main` (excluding file attachments). The Xata app bot will leave a comment with the details. +Once you are happy with your changes you should commit your files and create a GitHub pull request for your Git branch. Xata's GitHub application will look for new files in your `.xata/migrations` folder so make sure they are included in the commit. Regardless of whether migrations are present, Xata will generate a preview branch for any pull request you deploy using a `preview-{branch_name}` naming system. This is done by forking the `main` branch, applying schema migrations from the pull request branch and copying over sample data from `main` (excluding file attachments). The Xata app bot will leave a comment with the details. -If you also have Vercel or Netlify configured for your repository you should see their bot make a similar comment. As long as your integrations were set up properly, the preview deployment that your host provides should be using the preview database that Xata provides. The workflow should be the same whether you are using the Netlify of Vercel integration. +If you also have Vercel or Netlify configured for your repository, you should see their bot make a similar comment. As long as your integrations were set up properly, the preview deployment that your host provides should use the preview database that Xata provides. The workflow should be the same whether you are using the Netlify of Vercel integration. ![Xata bot on GitHub](images/xata-bot.png) diff --git a/040-SDK/020-Python/020-examples.mdx b/040-SDK/020-Python/020-examples.mdx index 9d2b6b7e..97f1d849 100644 --- a/040-SDK/020-Python/020-examples.mdx +++ b/040-SDK/020-Python/020-examples.mdx @@ -486,7 +486,7 @@ print(to_rfc339(date_with_tz, tz_europe_vienna)) The Xata SDK provides schema editing operations under the [Table](https://xata-py.readthedocs.io/en/latest/api.html#xata.api.table.Table) class. -You can create tables, add and delete columns, or set the full table schema at once. +You can create tables, add and delete columns, or set the full table schema. ```python from xata.client import XataClient diff --git a/040-SDK/030-Go/010-overview.mdx b/040-SDK/030-Go/010-overview.mdx new file mode 100644 index 00000000..b2f4f423 --- /dev/null +++ b/040-SDK/030-Go/010-overview.mdx @@ -0,0 +1,75 @@ +--- +title: Xata SDK for Go +navTitle: SDK overview +keywords: ['go', 'golang', 'sdk'] +description: Get to know Xata using Go +slug: sdk/go/overview +published: true +--- + + + The Go SDK is currently in *alpha*. This means that it does not include all endpoints and is subject to potential + breaking changes before reaching its `1.0.0` stable General Availability (GA) release. + + +The Go SDK is available on GitHub: https://github.com/xataio/xata-go + +## Install + +```bash +go get github.com/xataio/xata-go@latest +``` + +## Configuration + +The client needs a `XATA_API_KEY` environment variables for authentication and the `.xatarc` file for the database URL. Refer to [our installation guide](/docs/getting-started/installation#xatarc) to initialize your project with the `.xatarc` file. + +## Example + +After setting up your project and adding Xata credentials, create an example Go file. + +The following example code demonstrates using the SDK to connect to Xata, retrieve a list of workspaces, and then print out details of the first workspace in the list. + +In your text editor, paste the following code into your `example.go` file and save the file: + +```go +package main + +import ( + "context" + "fmt" + + "github.com/xataio/xata-go/xata" +) + +func main() { + workspaces, _ := xata.NewWorkspacesClient() + resp, _ := workspaces.List(context.TODO()) + fmt.Printf("%#v\n", *resp.Workspaces[0]) +} +``` + +In the terminal, enter `go run .` to run the code. + +The code snippet calls `workspaces.List(ctx)` API to list all workspaces and prints the details of the first workspace with `fmt.Printf("%#v\n", *resp.Workspaces[0])`. + +### Runnable Example + +You can run the snippet from above on your machine by, pulling the example code from the xataio/xata-go repository + +```bash +wget -O example.go "https://raw.githubusercontent.com/xataio/xata-go/main/examples/list_workspaces.go" +go mod edit -module=example.com/mod +go mod download github.com/xataio/xata-go@main +``` + +Run the code with the command: + +```bash +XATA_API_KEY="" go run example.go +``` + +## Known Limitations + +- [Numeric operations](/docs/sdk/update#numeric-operations) are currently not supported using the update API. As a workaround, you can use the transaction API [example](/docs/sdk/transaction). +- Not all Xata endpoints are available at the alpha state of the SDK. You can check the coverage [here](https://github.com/xataio/xata-go/issues/1). diff --git a/040-SDK/101-get.mdx b/040-SDK/101-get.mdx index 354f9b05..d7f15cb9 100644 --- a/040-SDK/101-get.mdx +++ b/040-SDK/101-get.mdx @@ -9,19 +9,19 @@ published: true The general form of a query is: - + ```ts import { getXataClient } from "./xata"; const client = getXataClient(); const data = await client -.db[table] -.select([...]) -.filter({ ... }) -.sort({ ... }) -.page({ ... }) -.getMany(); + .db[table] + .select([...]) + .filter({ ... }) + .sort({ ... }) + .page({ ... }) + .getMany(); ``` ```python @@ -38,6 +38,26 @@ data = xata.data().query("{table_name}", { ... }, "page": { + ... + } +}) +``` + +```go +searchClient, _ := xata.NewSearchAndFilterClient() +data, _ := searchClient.Query(context.TODO(), xata.QueryTableRequest{ + TableName: "{tabel_name}", + Payload: xata.QueryTableRequestPayload{ + Columns: []string{"col_1", ".."}, + Filter: &xata.FilterExpression{ + // .. + }, + Sort: xata.NewSortExpressionFromStringSortOrderMapList( + // .. + ), + Page: &xata.SearchPageConfig{ + // .. + }, } }) ``` @@ -62,6 +82,7 @@ data = xata.data().query("{table_name}", { ... }, "page": { + ... } } ``` @@ -72,7 +93,7 @@ For the REST API example, note that a POST request is used, even though the data All the requests are optional, so the simplest query request looks like this: - + ```ts const teams = await xata.db.Teams.getMany(); @@ -82,6 +103,13 @@ const teams = await xata.db.Teams.getMany(); teams = xata.data().query("Teams") ``` +```go +client, _ := xata.NewSearchAndFilterClient() +teams, _ := data.Query(context.TODO(), xata.QueryTableRequest{ + TableName: "Teams", +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -98,7 +126,7 @@ teams = xata.data().query("Teams") The response looks like this: - + ```ts [ { @@ -112,26 +140,32 @@ The response looks like this: ``` ```python - "records": [ - { - "id": "rec_c8hng2h26un90p8sr7k0", - "name": "Matrix", - "owner": { - "id": "myid" - }, - "xata": { - "version": 0, - "createdAt": "2023-05-15T08:21:31.96526+01:00", - "updatedAt": "2023-05-15T21:58:54.072595+01:00" - } - } - ], - "meta": { - "page": { - "cursor": "jMq7DcIwEIDhnjH-2sWRAsItAT2KkOU8bAgB3Zkqyu6IDei_", - "more": false +"records": [ + { + "id": "rec_c8hng2h26un90p8sr7k0", + "name": "Matrix", + "owner": { + "id": "myid" + }, + "xata": { + "version": 0, + "createdAt": "2023-05-15T08:21:31.96526+01:00", + "updatedAt": "2023-05-15T21:58:54.072595+01:00" } } +], +"meta": { + "page": { + "cursor": "jMq7DcIwEIDhnjH-2sWRAsItAT2KkOU8bAgB3Zkqyu6IDei_", + "more": false + } +} +``` + +```go +// type QueryTableResponse +Meta *RecordsMetadata +Records []*Record ``` ```json @@ -226,7 +260,7 @@ Unless there's a specific reason to prefer another method, getMany() is generall You can retrieve a record with a given ID using a request like this: - + ```ts const user = await xata.db.Users.read('myid'); @@ -236,6 +270,17 @@ const user = await xata.db.Users.read('myid'); user = xata.records().get("Users", "myid") ``` +```go +client, _ := xata.NewRecordsClient() +user, _ := client.Get(context.TODO(), xata.GetRecordRequest{ + RecordRequest: xata.RecordRequest{ + DatabaseName: xata.String("{db}"), + TableName: "Users", + }, + RecordID: "myid", +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -257,7 +302,7 @@ By default, the Query API returns all columns of the queried table. For link col For example, if you are only interested in the name and the city of the user, you can make a request like this: - + ```ts const users = await xata.db.Users.select(['name', 'city']).getMany(); @@ -269,6 +314,16 @@ users = xata.data().query("Users", { }) ``` +```go +client, err := xata.NewSearchAndFilterClient() +users, _ := client.Query(context.TODO(), xata.QueryTableRequest{ + TableName: "Users", + Payload: xata.QueryTableRequestPayload{ + Columns: []string{"name", "city"}, + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -310,7 +365,7 @@ It's worth noting that the special columns [id](/docs/concepts/data-model#id), [ The same syntax can be used to select columns from a linked table, therefore adding new columns to the response. For example, to query all the columns of the teams table and also add all the columns of the owner user, you can use: - + ```ts const teams = await xata.db.Teams.select(['*', 'owner.*']).getMany(); @@ -322,6 +377,16 @@ users = xata.data().query("Users", { }) ``` +```go +client, err := xata.NewSearchAndFilterClient() +users, _ := client.Query(context.TODO(), xata.QueryTableRequest{ + TableName: "Users", + Payload: xata.QueryTableRequestPayload{ + Columns: []string{"*", "owner.*"}, + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -341,7 +406,7 @@ users = xata.data().query("Users", { You can do this transitively as well, for example: - + ```ts const posts = await xata.db.Posts.select([ "title", @@ -360,6 +425,20 @@ posts = xata.data().query("Posts", { }) ``` +```go +client, err := xata.NewSearchAndFilterClient() +users, _ := client.Query(context.TODO(), xata.QueryTableRequest{ + TableName: "Users", + Payload: xata.QueryTableRequestPayload{ + Columns: []string{ + "title", + "author.*", + "author.team.*", + }, + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -382,7 +461,7 @@ In this example, the `author` is a link column from `Posts` to `Users` and `team By default, when retrieving a record by its ID, only the ID column of linked records is included in the response. However, you have the option to request the linked columns to be expanded. In the following examples, the code is using the `.read()` method to retrieve a record with the ID `myid` from the `Posts` table. The code specifies it wants the `author` column to be expanded and to retrieve more information from the `author` linked record. - + ```ts const user = await xata.db.Posts.read('myid', ['author.*']); @@ -392,6 +471,18 @@ const user = await xata.db.Posts.read('myid', ['author.*']); user = xata.records().get("Posts", "myid", columns=["author.*"]) ``` +```go +client, _ := xata.NewRecordsClient() +record, _ := client.Get(context.TODO(), xata.GetRecordRequest{ + RecordRequest: xata.RecordRequest{ + DatabaseName: xata.String("{db}"), + TableName: "Users", + }, + RecordID: "myid", + Columns: []string{"author.*"}, + }) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql diff --git a/040-SDK/102-create.mdx b/040-SDK/102-create.mdx index 76b5d6ef..151fa1ba 100644 --- a/040-SDK/102-create.mdx +++ b/040-SDK/102-create.mdx @@ -20,7 +20,7 @@ published: true You can create a record like this: - + ```ts const record = await xata.db.Users.create({ @@ -36,6 +36,19 @@ record = xata.records().insert("Users", { }) ``` +```go +client, _ := xata.NewRecordsClient() +record, _ := client.Insert(context.TODO(), xata.InsertRecordRequest{ + RecordRequest: xata.RecordRequest{ + TableName: "Users", + }, + Body: map[string]*xata.DataInputRecordValue{ + "email": xata.ValueFromString("keanu@example.com"), + "name": xata.ValueFromString("Keanu Reeves"), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -121,7 +134,7 @@ If you want to return more columns, you can specify them via the `columns` param If you want to specify your own ID, you can do it like this: - + ```ts const record = await xata.db.Users.create('myid', { email: 'keanu@example.com', @@ -136,6 +149,20 @@ record = xata.records().insert_with_id("Users", "myid", { }) ``` +```go +client, _ := xata.NewRecordsClient() +record, err := client.InsertWithID(context.TODO(), xata.InsertRecordWithIDRequest{ + RecordRequest: xata.RecordRequest{ + TableName: "Users", + }, + RecordID: "myid", + Body: map[string]*xata.DataInputRecordValue{ + "email": xata.ValueFromString("keanu@example.com"), + "name": xata.ValueFromString("Keanu Reeves"), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -161,7 +188,7 @@ In the REST API example, note the change from `POST` to `PUT`. The `createOnly` In the schema that we chose, the `Posts` table has an `author` column of type `link` that links to the `Users` table. To insert a record with a linked field, use the ID of the target record in the link column. - + ```ts const record = await xata.db.Posts.create({ title: 'Filming the Matrix', @@ -176,6 +203,19 @@ record = xata.records().insert("Posts", { }) ``` +```go +client, _ := xata.NewRecordsClient() +record, _ := client.Insert(context.TODO(), xata.InsertRecordRequest{ + RecordRequest: xata.RecordRequest{ + TableName: "Users", + }, + Body: map[string]*xata.DataInputRecordValue{ + "title": xata.ValueFromString("Filming the Matrix"), + "author": xata.ValueFromString("rec_cd8rqcoavc42pi67lgd0"), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -199,7 +239,7 @@ record = xata.records().insert("Posts", { If you have multiple records to insert, you can send them in a single request via the [`/bulk` endpoint](/api-reference/db/db_branch_name/tables/table_name/bulk#bulk-insert-table-records). For example: - + ```ts const users = await xata.db.Users.create([ { @@ -242,6 +282,33 @@ users = xata.records().bulk_insert("Users", { }) ``` +```go +client, _ := xata.NewRecordsClient() +users, _ := client.BulkInsert(context.TODO(), xata.BulkInsertRecordRequest{ + RecordRequest: xata.RecordRequest{ + TableName: "Users", + }, + Columns: []string{"name"}, + Records: []map[string]*xata.DataInputRecordValue{ + { + "email": xata.ValueFromString("laurence@example.com"), + "name": xata.ValueFromString("Laurence Fishburne"), + "team": xata.ValueFromString("rec_cd8s4kbo8dsvsjilo1ug"), + }, + { + "email": xata.ValueFromString("hugo@example.com"), + "name": xata.ValueFromString("Hugo Weaving"), + "team": xata.ValueFromString("rec_cd8s4kbo8dsvsjilo1ug"), + }, + { + "email": xata.ValueFromString("joe@example.com"), + "name": xata.ValueFromString("Joe Pantoliano"), + "team": xata.ValueFromString("rec_cd8s4kbo8dsvsjilo1ug"), + }, + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql diff --git a/040-SDK/103-update.mdx b/040-SDK/103-update.mdx index 157c1033..5c74d60d 100644 --- a/040-SDK/103-update.mdx +++ b/040-SDK/103-update.mdx @@ -11,7 +11,7 @@ published: true You can overwrite a full record with a request like this: - + ```ts const user = await xata.db.Users.createOrReplace('myid', { name: 'Keanu Reeves' }); @@ -23,6 +23,19 @@ user = xata.records().upsert("Users", "myid", { }) ``` +```go +client, _ := xata.NewRecordsClient() +user, _ := client.Upsert(context.TODO(), xata.UpsertRecordRequest{ + RecordRequest: xata.RecordRequest{ + TableName: "Users", + }, + RecordID: "myid", + Body: map[string]*xata.DataInputRecordValue{ + "name": xata.ValueFromString("Keanu Reeves"), + }, +}) +``` + ```jsonc // PUT https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/data/{record_id} @@ -39,7 +52,7 @@ Note that in the above example, the whole record was overwritten. If you want to In order to do a partial update to a record, you can use a request like this: - + ```ts const user = await xata.db.Users.update('myid', { email: 'newemail@example.com' }); @@ -55,6 +68,19 @@ user = xata.records().update("Users", "myid", { }) ``` +```go +client, _ := xata.NewRecordsClient() +user, _ := client.Update(context.TODO(), xata.UpdateRecordRequest{ + RecordRequest: xata.RecordRequest{ + TableName: "Users", + }, + RecordID: "myid", + Body: map[string]*xata.DataInputRecordValue{ + "email": xata.ValueFromString("newemail@example.com"), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -76,7 +102,7 @@ user = xata.records().update("Users", "myid", { It's also possible to update a record if it exists, or create it if it doesn't exist: - + ```ts const user = await xata.db.Users.createOrUpdate('myid', { name: 'Keanu Reeves' }); @@ -88,6 +114,19 @@ user = xata.records().upsert("Users", "myid", { }) ``` +```go +client, _ := xata.NewRecordsClient() +user, _ := client.Upsert(context.TODO(), xata.UpsertRecordRequest{ + RecordRequest: xata.RecordRequest{ + TableName: "Users", + }, + RecordID: "myid", + Body: map[string]*xata.DataInputRecordValue{ + "name": xata.ValueFromString("Keanu Reeves"), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -119,7 +158,7 @@ The numeric types (int and float) support basic mathematical operations: additio Here is a simple example that increments a counter: - + ```ts const user = await xata.db.Users.update('rec_c8hnbch26un1nl0rthkg', { counter: { $increment: 1 } }); @@ -133,6 +172,19 @@ user = xata.records().update("Users", "rec_c8hnbch26un1nl0rthkg", { }) ``` +```go +recordsClient, _ := xata.NewRecordsClient() +user, _ := recordsClient.Transaction(context.TODO(), xata.TransactionRequest{ + Operations: []xata.TransactionOperation{ + xata.NewUpdateTransaction(xata.TransactionUpdateOp{ + Table: "Users", + Id: "rec_c8hnbch26un1nl0rthkg", + Fields: map[string]any{"counter": map[string]int{"$increment": *xata.Int(1)}}, + }), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -156,7 +208,7 @@ user = xata.records().update("Users", "rec_c8hnbch26un1nl0rthkg", { And here is an example that adds 10 to the counter: - + ```ts const user = await xata.db.Users.update('rec_c8hnbch26un1nl0rthkg', { counter: { $increment: 10 } }); @@ -170,6 +222,19 @@ user = xata.records().update("Users", "rec_c8hnbch26un1nl0rthkg", { }) ``` +```go +recordsClient, _ := xata.NewRecordsClient() +user, _ := recordsClient.Transaction(context.TODO(), xata.TransactionRequest{ + Operations: []xata.TransactionOperation{ + xata.NewUpdateTransaction(xata.TransactionUpdateOp{ + Table: "Users", + Id: "rec_c8hnbch26un1nl0rthkg", + Fields: map[string]any{"counter": map[string]int{"$increment": *xata.Int(10)}}, + }), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -193,7 +258,7 @@ user = xata.records().update("Users", "rec_c8hnbch26un1nl0rthkg", { And here is an example that divides the counter by 2: - + ```ts const user = await xata.db.Users.update('rec_c8hnbch26un1nl0rthkg', { counter: { $divide: 2 } }); @@ -207,6 +272,19 @@ user = xata.records().update("Users", "rec_c8hnbch26un1nl0rthkg", { }) ``` +```go +recordsClient, _ := xata.NewRecordsClient() +user, _ := recordsClient.Transaction(context.TODO(), xata.TransactionRequest{ + Operations: []xata.TransactionOperation{ + xata.NewUpdateTransaction(xata.TransactionUpdateOp{ + Table: "Users", + Id: "rec_c8hnbch26un1nl0rthkg", + Fields: map[string]any{"counter": map[string]int{"$divide": *xata.Int(2)}}, + }), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -303,7 +381,7 @@ The `version` field can be used to perform optimistic concurrency control, also To prevent this, you can pass the `ifVersion` parameter to the PUT request. The value for `ifVersion` should be the value of `xata.version` from when you retrieved the record. For example, if you want to update the record only if the version is 0, you can send the following request: - + ```ts const updatedUser = await xata.db.Users.update( @@ -330,6 +408,21 @@ user = xata.records().update( ) ``` +```go +client, _ := xata.NewRecordsClient() +user, _ := client.Update(context.TODO(), xata.UpdateRecordRequest{ + RecordRequest: xata.RecordRequest{ + TableName: "Users", + }, + RecordID: "rec_c8hnbch26un1nl0rthkg", + Body: map[string]*xata.DataInputRecordValue{ + "name": xata.ValueFromString("Keanu Reeves"), + "email": xata.ValueFromString("keanu@xata.io"), + }, + IfVersion: xata.Int(0), +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql diff --git a/040-SDK/104-delete.mdx b/040-SDK/104-delete.mdx index 17b7d80e..6459b6b4 100644 --- a/040-SDK/104-delete.mdx +++ b/040-SDK/104-delete.mdx @@ -9,7 +9,7 @@ published: true To delete a record you can execute, for example: - + ```ts const user = await xata.db.Users.delete('rec_cd8s3r8avc42pi67m13g'); @@ -22,6 +22,17 @@ user.delete(); user = xata.records().delete("Users", "rec_cd8s3r8avc42pi67m13g") ``` +```go +client, _ := xata.NewRecordsClient() +response = client.Delete(context.TODO(), xata.DeleteRecordRequest{ + RecordRequest: xata.RecordRequest{ + DatabaseName: xata.String("{db}"), + TableName: "Users", + }, + RecordID: "rec_cd8s3r8avc42pi67m13g", +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql @@ -41,7 +52,7 @@ In case the record with the given ID doesn't exist, the REST API returns a 404 a Transactions are used when deleting multiple records: - + ```ts const users = await xata.db.Users.delete(['rec_cd8s3r8avc42pi67m13g', 'rec_cgh9o1oncchhigq95n2g']); @@ -66,6 +77,25 @@ users = xata.records().transaction({ }) ``` +```go +client, _ := xata.NewRecordsClient() +users, _ := client.Transaction(context.TODO(), xata.TransactionRequest{ + RecordRequest: xata.RecordRequest{ + DatabaseName: xata.String("{db}"), + }, + Operations: []xata.TransactionOperation{ + xata.NewDeleteTransaction(xata.TransactionDeleteOp{ + Table: "Users", + Id: "rec_cd8s3r8avc42pi67m13g", + }), + xata.NewDeleteTransaction(xata.TransactionDeleteOp{ + Table: "Users", + Id: "rec_cgh9o1oncchhigq95n2g", + }), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/sql diff --git a/040-SDK/111-search.mdx b/040-SDK/111-search.mdx index f7b4aa94..5f10bb81 100644 --- a/040-SDK/111-search.mdx +++ b/040-SDK/111-search.mdx @@ -75,7 +75,7 @@ results = xata.data().search_branch({ A simple example, which searches across all tables with default relevancy settings, looks like this: - + ```ts const results = await xata.search.all('new st'); @@ -85,6 +85,15 @@ const results = await xata.search.all('new st'); results = xata.data().search_branch({"query": "new st"}) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +results, _ := searchClient.SearchBranch(context.TODO(), xata.SearchBranchRequest{ + Payload: xata.SearchBranchRequestPayload{ + Query: "new st", + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/search @@ -206,7 +215,7 @@ The metadata includes: If you'd like to search only some of the tables in the database, you can specify the tables to search in the `tables` field of the request. It expects an array, for example: - + ```ts const results = await xata.search.all('new st', { @@ -235,6 +244,19 @@ results = xata.data().search_branch({ }) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +results, _ := searchClient.SearchBranch(context.TODO(), xata.SearchBranchRequest{ + Payload: xata.SearchBranchRequestPayload{ + Query: "new st", + Tables: []*xata.SearchBranchRequestTablesItem{ + xata.NewSearchBranchRequestTablesItemFromString("Users"), + xata.NewSearchBranchRequestTablesItemFromString("Posts"), + }, + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/search @@ -311,7 +333,7 @@ By default, Xata searches tolerate typos of one character. You can control this For example, instead of `Keanu` you can search for `kaanu` (one letter replaced) or `kenu` (one letter missing) and still get the same result: - + ```ts const results = await xata.search.all('kaanu'); @@ -321,6 +343,15 @@ const results = await xata.search.all('kaanu'); results = xata.data().search_branch({"query": "kaanu"}) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +results, _ := searchClient.SearchBranch(context.TODO(), xata.SearchBranchRequest{ + Payload: xata.SearchBranchRequestPayload{ + Query: "kaanu", + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/search @@ -333,7 +364,7 @@ results = xata.data().search_branch({"query": "kaanu"}) The above matches `Keanu`. You can disable this typo tolerance by setting the `fuzziness` field to 0: - + ```ts const results = await xata.search.all('kaanu', { fuzziness: 0 }); @@ -346,6 +377,16 @@ results = xata.data().search_branch({ }) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +results, _ := searchClient.SearchBranch(context.TODO(), xata.SearchBranchRequest{ + Payload: xata.SearchBranchRequestPayload{ + Query: "kaanu", + Fuzziness: xata.Int(0), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/search @@ -361,7 +402,7 @@ The above won't match `Keanu`. You can also increase the `fuzziness` to accept two typos per word: - + ```ts const results = await xata.search.all('kaano', { fuzziness: 2 }); @@ -374,6 +415,16 @@ results = xata.data().search_branch({ }) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +results, _ := searchClient.SearchBranch(context.TODO(), xata.SearchBranchRequest{ + Payload: xata.SearchBranchRequestPayload{ + Query: "kaanu", + Fuzziness: xata.Int(2), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/search diff --git a/040-SDK/111-vector-search.mdx b/040-SDK/111-vector-search.mdx index 6a81da52..047e6f3e 100644 --- a/040-SDK/111-vector-search.mdx +++ b/040-SDK/111-vector-search.mdx @@ -18,7 +18,7 @@ An embedding is a vector of floating point numbers that represents the original Vector search works at the table level and has the following format: - + ```ts const results = await xata.db.Docs.vectorSearch( @@ -42,6 +42,20 @@ results = xata.data().vector_search("Docs", { }) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +results, _ := searchClient.VectorSearch(context.TODO(), xata.VectorSearchTableRequest{ + TableName: "Docs", + Payload: xata.VectorSearchTableRequestPayload{ + QueryVector: []float64{0.1, 0.2}, // array of floats + Column: "embeddings", // column name + SimilarityFunction: xata.String("l1"), // space function + Size: xata.Int(5), // number of results to return + Filter: &xata.FilterExpression{}, // filter expression + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/vectorSearch { @@ -68,7 +82,7 @@ Additionally you can customize the results with these optional parameters: Here is a simple example: - + ```ts const results = await xata.db.Docs.vectorSearch('embeddings', [0.1, 0.2, 0.3], { size: 5 }); @@ -82,6 +96,18 @@ results = xata.data().vector_search("Docs", { }) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +results, _ := searchClient.VectorSearch(context.TODO(), xata.VectorSearchTableRequest{ + TableName: "Docs", + Payload: xata.VectorSearchTableRequestPayload{ + QueryVector: []float64{0.1, 0.2, 0.3}, // array of floats + Column: "embeddings", // column name + Size: xata.Int(5), // number of results to return + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/vectorSearch { diff --git a/040-SDK/130-transaction.mdx b/040-SDK/130-transaction.mdx index 7c9b5965..dc6afbd4 100644 --- a/040-SDK/130-transaction.mdx +++ b/040-SDK/130-transaction.mdx @@ -35,17 +35,17 @@ The Xata transactions API can be thought of as a way to wrap our existing insert We'll start by taking a look at a full request-response, and then we'll step into each operation and its options. - - ```ts - const result = await xata.transactions.run([ - { insert: { table: 'titles', record: { originalTitle: 'A new film' } } }, - { insert: { table: 'titles', record: { id: 'new-0', originalTitle: 'The squeel' }, createOnly: true } }, - { update: { table: 'titles', id: 'new-0', fields: { originalTitle: 'The sequel' }, ifVersion: 0 } }, - { update: { table: 'titles', id: 'new-1', fields: { originalTitle: 'The third' }, upsert: true } }, - { get: { table: 'titles', id: 'new-0', columns: ['id', 'originalTitle'] } }, - { delete: { table: 'titles', id: 'new-0' } } - ]); - ``` + +```ts +const result = await xata.transactions.run([ + { insert: { table: 'titles', record: { originalTitle: 'A new film' } } }, + { insert: { table: 'titles', record: { id: 'new-0', originalTitle: 'The squeel' }, createOnly: true } }, + { update: { table: 'titles', id: 'new-0', fields: { originalTitle: 'The sequel' }, ifVersion: 0 } }, + { update: { table: 'titles', id: 'new-1', fields: { originalTitle: 'The third' }, upsert: true } }, + { get: { table: 'titles', id: 'new-0', columns: ['id', 'originalTitle'] } }, + { delete: { table: 'titles', id: 'new-0' } } +]); +``` ```python result = xata.records().transaction({ @@ -57,7 +57,53 @@ result = xata.records().transaction({ { "get": { "table": "titles", "id": "new-0", "columns": ["id", "originalTitle"] } }, { "delete": { "table": "titles", "id": "new-0" } } ] -}); +}) +``` + +```go +recordsClient, _ := xata.NewRecordsClient() +result, _ := recordsClient.Transaction(context.TODO(), xata.TransactionRequest{ + Operations: []xata.TransactionOperation{ + xata.NewInsertTransaction(xata.TransactionInsertOp{ + Table: "titles", + Record: map[string]any{ + "originalTitle": xata.String("a new film"), + }, + }), + xata.NewInsertTransaction(xata.TransactionInsertOp{ + Table: "titles", + Record: map[string]any{ + "id": xata.String("new-0"), + "originalTitle": xata.String("the sequeel"), + }, + CreateOnly: xata.Bool(true), + }), + xata.NewUpdateTransaction(xata.TransactionUpdateOp{ + Table: "titles", + Id: "new-0", + Fields: map[string]any{ + "originalTitle": xata.String("the sequel"), + }, + IfVersion: xata.Int(0), + }), + xata.NewUpdateTransaction(xata.TransactionUpdateOp{ + Table: "titles", + Id: "new-1", + Fields: map[string]any{ + "originalTitle": xata.String("the third"), + }, + Upsert: xata.Bool(true), + }), + xata.NewGetTransaction(xata.TransactionGetOp{ + Table: "titles", + Id: "new-0", + }), + xata.NewDeleteTransaction(xata.TransactionDeleteOp{ + Table: "titles", + Id: "new-0", + }), + }, +}) ``` ```jsonc @@ -124,18 +170,18 @@ Xata will return the ID to you. By default, if a record exists with the same explicit ID, Xata will overwrite the record. You can adjust this behavior by setting `createOnly` to `true` for the operation. - - ```ts - const result = await xata.transactions.run([ - { - insert: { - table: 'titles', - record: { id: 'rec_cfl4g6v838og05h0iv6g', originalTitle: 'A new film' }, - createOnly: true - } + +```ts +const result = await xata.transactions.run([ + { + insert: { + table: 'titles', + record: { id: 'rec_cfl4g6v838og05h0iv6g', originalTitle: 'A new film' }, + createOnly: true } - ]); - ``` + } +]); +``` ```python result = xata.records().transactions({ @@ -151,6 +197,22 @@ result = xata.records().transactions({ }) ``` +```go +recordsClient, _ := xata.NewRecordsClient() +result, _ := recordsClient.Transaction(context.TODO(), xata.TransactionRequest{ + Operations: []xata.TransactionOperation{ + xata.NewInsertTransaction(xata.TransactionInsertOp{ + Table: "titles", + Record: map[string]any{ + "id": xata.String("rec_cfl4g6v838og05h0iv6g"), + "originalTitle": xata.String("A new film"), + }, + CreateOnly: xata.Bool(true), + }), + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/transaction { diff --git a/040-SDK/140-ask.mdx b/040-SDK/140-ask.mdx index 733919a0..c828f95f 100644 --- a/040-SDK/140-ask.mdx +++ b/040-SDK/140-ask.mdx @@ -27,7 +27,7 @@ When you use the `ask` endpoint, you can choose to continue any conversation you The `ask` endpoint has the following general form: - + ```ts const result = await xata.db.Tutorial.ask('', { @@ -91,35 +91,61 @@ result = xata.data().ask( ) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() + +searchType := xata.AskTableRequestSearchTypeKeyword +prefix := xata.PrefixExpressionPhrase + +result, _ := searchClient.Ask(context.TODO(), xata.AskTableRequest{ + TableName: "Tutorial", // reference table + Payload: xata.AskTableRequestPayload{ + Question: "", // question to ask + SearchType: &searchType, // keyword | vector + Search: &xata.AskTableRequestSearch{ + Target: []*xata.TargetExpressionItem{}, // search target options + Prefix: &prefix, // phrase | disabled + Filter: &xata.FilterExpression{}, // search filter options + Boosters: []*xata.BoosterExpression{}, // search booster options + }, + VectorSearch: &xata.AskTableRequestVectorSearch{ + Column: "embeddings", // columns with embeddings + ContentColumn: "description", // column with content + Filter: &xata.FilterExpression{}, // search filter options + }, + }, +}) +``` + ```jsonc - // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/ask - { - "question": "", - "rules": [ - // ...array of strings with the rules for the model..., - ], - "searchType": "keyword|vector", - "search": { - "fuzziness": 0|1|2, - "prefix": "phrase|disabled", - "target": { - // ...search target options... - }, - "filter": { - // ...search filter options... - }, - "boosters": [ - // ...search boosters options... - ] - }, - "vectorSearch": { - "column": "", - "contentColumn": "", - "filter": { - // ...search filter options... - } - } - } +// POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/ask +{ + "question": "", + "rules": [ + // ...array of strings with the rules for the model..., + ], + "searchType": "keyword|vector", + "search": { + "fuzziness": 0|1|2, + "prefix": "phrase|disabled", + "target": { + // ...search target options... + }, + "filter": { + // ...search filter options... + }, + "boosters": [ + // ...search boosters options... + ] + }, + "vectorSearch": { + "column": "", + "contentColumn": "", + "filter": { + // ...search filter options... + } + } +} ``` @@ -206,7 +232,7 @@ When communicating with OpenAI, the `ask` endpoint ensures that your rules, your Each session maintains its own cached set of your context, so changes to the underlying data in your database will not affect ongoing conversations. All cached information: your context, rules, and all conversations are automatically removed after 7 days. - + ```ts const result = await xata.db.Tutorial.ask('', { sessionId: '' }); @@ -216,6 +242,15 @@ const result = await xata.db.Tutorial.ask('', { sessionI result = xata.data().ask_follow_up("Tutorial", "", "") ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +result, _ := searchClient.AskFollowUp(context.TODO(), xata.AskFollowUpRequest{ + TableName: "Tutorial", + Question: "", + SessionID: "", +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/ask/ { @@ -233,7 +268,7 @@ To index your custom data in Xata, you can use, for example, this [web crawler]( The following is the simplest example of using the `ask` endpoint: - + ```ts const result = await xata.db.Tutorial.ask('What is this tutorial about?'); @@ -243,6 +278,14 @@ const result = await xata.db.Tutorial.ask('What is this tutorial about?'); result = xata.data().ask("Tutorial", "What is this tutorial about?") ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +result, _ := searchClient.Ask(context.TODO(), xata.AskRequest{ + TableName: "Tutorial", + Question: "", +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/ask { @@ -256,7 +299,7 @@ Because the search step is not specified, keyword search is being used with the The following example tunes the rules and the search step, while still using keyword search: - + ```ts const result = await xata.db.Tutorial.ask('How do I retrieve a single record?', { @@ -314,6 +357,53 @@ result = xata.data().ask( ) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +kw := xata.AskTableRequestSearchTypeKeyword +pep := xata.PrefixExpressionPhrase +rules := []string{ + "Do not answer questions about pricing or the free tier. Respond that Xata has several options available, please check https://xata.io/pricing for more information.", + "When you give an example, this example must exist exactly in the context given.", + "Only answer questions that are relating to the defined context or are general technical questions. If asked about a question outside of the context, you can respond with \"It doesn't look like I have enough information to answer that. Check the documentation or contact support.\"", + "Your name is DanGPT", +} + +result, _ := searchClient.Ask(context.TODO(), xata.AskTableRequest{ + TableName: "Tutorial", + Payload: xata.AskTableRequestPayload{ + Question: "How do I retrieve a single record?", + SearchType: &kw, // keyword + Rules: &rules, + Search: &xata.AskTableRequestSearch{ + Fuzziness: xata.Int(2), + Prefix: &pep, // phrase + Target: []*xata.TargetExpressionItem{ + xata.NewTargetExpression("slug"), + xata.NewTargetExpressionWithColumnObject(xata.TargetExpressionItemColumn{ + Column: "title", + Weight: xata.Float64(4), + }), + xata.NewTargetExpression("content"), + xata.NewTargetExpression("section"), + xata.NewTargetExpressionWithColumnObject(xata.TargetExpressionItemColumn{ + Column: "keywords", + Weight: xata.Float64(4), + }), + }, + Boosters: []*xata.BoosterExpression{ + xata.NewBoosterExpressionFromBoosterExpressionValueBooster(&xata.BoosterExpressionValueBooster{ + ValueBooster: &xata.ValueBooster{ + Column: "section", + Value: xata.NewValueBoosterValueFromString("guide"), + Factor: 10, + }, + }), + }, + }, + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/ask { @@ -349,22 +439,22 @@ The following example uses vector search: ```ts const result = await xata.db.Tutorial.ask("How do a retrieve a single record?", { - rules: [ - "Do not answer questions about pricing or the free tier. Respond that Xata has several options available, please check https://xata.io/pricing for more information.", - "If the user asks a how-to question, provide a code snippet in the language they asked for with TypeScript as the default.", - "Only answer questions that are relating to the defined context or are general technical questions. If asked about a question outside of the context, you can respond with \"It doesn't look like I have enough information to answer that. Check the documentation or contact support.\"", - "Results should be relevant to the context provided and match what is expected for a cloud database.", - "If the question doesn't appear to be answerable from the context provided, but seems to be a question about TypeScript, Javascript, or REST APIs, you may answer from outside of the provided context.", - "Your name is DanGPT" - ], - searchType: "vector", - vectorSearch: { - column: "embeddings", - contentColumn: "content", - filter: { - section: "guide" - } - } + rules: [ + "Do not answer questions about pricing or the free tier. Respond that Xata has several options available, please check https://xata.io/pricing for more information.", + "If the user asks a how-to question, provide a code snippet in the language they asked for with TypeScript as the default.", + "Only answer questions that are relating to the defined context or are general technical questions. If asked about a question outside of the context, you can respond with \"It doesn't look like I have enough information to answer that. Check the documentation or contact support.\"", + "Results should be relevant to the context provided and match what is expected for a cloud database.", + "If the question doesn't appear to be answerable from the context provided, but seems to be a question about TypeScript, Javascript, or REST APIs, you may answer from outside of the provided context.", + "Your name is DanGPT" + ], + searchType: "vector", + vectorSearch: { + column: "embeddings", + contentColumn: "content", + filter: { + section: "guide" + } + } }) ``` @@ -421,7 +511,7 @@ result = xata.data().ask( The following example shows a conversation. - + ```ts const result = await xata.db.Tutorial.ask("What's the difference between summarize and aggregate?", { @@ -479,6 +569,53 @@ result = xata.data().ask( ) ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +kw := xata.AskTableRequestSearchTypeKeyword +pep := xata.PrefixExpressionPhrase +rules := []string{ + "Do not answer questions about pricing or the free tier. Respond that Xata has several options available, please check https://xata.io/pricing for more information.", + "When you give an example, this example must exist exactly in the context given.", + "Only answer questions that are relating to the defined context or are general technical questions. If asked about a question outside of the context, you can respond with \"It doesn't look like I have enough information to answer that. Check the documentation or contact support.\"", + "Your name is DanGPT", +} + +result, _ := searchClient.Ask(context.TODO(), xata.AskTableRequest{ + TableName: "Tutorial", + Payload: xata.AskTableRequestPayload{ + Question: "What's the difference between summarize and aggregate?", + SearchType: &kw, // keyword + Rules: &rules, + Search: &xata.AskTableRequestSearch{ + Fuzziness: xata.Int(2), + Prefix: &pep, // phrase + Target: []*xata.TargetExpressionItem{ + xata.NewTargetExpression("slug"), + xata.NewTargetExpressionWithColumnObject(xata.TargetExpressionItemColumn{ + Column: "title", + Weight: xata.Float64(4), + }), + xata.NewTargetExpression("content"), + xata.NewTargetExpression("section"), + xata.NewTargetExpressionWithColumnObject(xata.TargetExpressionItemColumn{ + Column: "keywords", + Weight: xata.Float64(4), + }), + }, + Boosters: []*xata.BoosterExpression{ + xata.NewBoosterExpressionFromBoosterExpressionValueBooster(&xata.BoosterExpressionValueBooster{ + ValueBooster: &xata.ValueBooster{ + Column: "section", + Value: xata.NewValueBoosterValueFromString("guide"), + Factor: 18, + }, + }), + }, + }, + }, +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/ask { @@ -521,7 +658,7 @@ From here, you might receive the following response: Now, using the `session_id` key returned in the response, we're able to continue the dialogue. - + ```ts const result = await xata.db.TutorialaskContinue('cg52bk1eqh5rd5hndhq95jercs', 'Can you show me an example of both?'); @@ -531,6 +668,15 @@ const result = await xata.db.TutorialaskContinue('cg52bk1eqh5rd5hndhq95jercs', ' result = xata.data().ask_follow_up("Tutorial", "Can you show me an example of both?", "cg52bk1eqh5rd5hndhq95jercs") ``` +```go +searchClient, _ := xata.NewSearchAndFilterClient() +result, _ := searchClient.AskFollowUp(context.TODO(), xata.AskFollowUpRequest{ + TableName: "Tutorial", + Question: "Can you show me an example of both?", + SessionID: "cg52bk1eqh5rd5hndhq95jercs", +}) +``` + ```jsonc // POST https://{workspace}.{region}.xata.sh/db/{db}:{branch}/tables/{table}/ask/cg52bk1eqh5rd5hndhq95jercs {