Elasticsearch return type

Viewed 727

I am trying to simply receive an inserted item, edit it and update it again. Unfortunately this doesn't go so smoothly.

The code is not finalized yet and is just POC'ing around, do not use like this in production if you intent to copy it :).

My create function which works fine:

async create(index: string, obj: any, id: string): Promise<TModel> {
    let req: RequestParams.Create<TModel> = {
        body: obj,
        index: index,
        id: id,
    };
    try {
        var result = await this.client.create(req, {
            ignore:[409]
        });
        if (result.statusCode === 201) {
            return result.body;
        } else {
            console.log("Non succesfull call, result:", result);
            return null;
        }
    } catch (error) {
        console.log("create error", error);
        return null;
    }
}

My update function which works about the same

async update(index: string, obj: any, id: string): Promise<TModel> {
    try {
        let req: RequestParams.Update<TModel> = {
            body: obj,
            index: index,
            id: id
        };
        var result = await this.client.update(req);
        if (result.statusCode === 200 || result.statusCode === 201 || result.statusCode == 202 || result.statusCode == 204) {
            return result.body;
        } else {
            console.log("Non succesfull call, result:", result);
            return null;
        }
    } catch (error) {
        console.error("Error updating", error);
    }
}

The search function I started with:

async search(index: string, searchBody: any): Promise<any> {

    try {
        var result = await this.client.search({
            index: index,
            body: searchBody
        });
        if (result.statusCode === 200) {
            return result.body.hits.hits;
        } else {
            console.log("Non succesfull call, result:", result);
            return null;
        }
    } catch (error) {
        console.log("Error getting result", error);
        return null;
    }
}

When inserting and later searching for an object, you of course get an any return type. Knowing how the data is structured, somewhere I do the following just for quickly testing:

return result.body.hits.hits[0]._source

Which gives me this as result:

enter image description here

Although the JSON-format of the object seems to be correct, just like I have created, it throws an error at updating the data:

error

So I googled and try to apply this solution, provided by elastic themselves:

https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/typescript.html

Search code:

async searchTyped(index: string, searchBody: any): Promise<TModel> {
    try {
        let req : RequestParams.Search<TModel> ={
            index : index,
             body : searchBody,
        };
        var result : ApiResponse<SearchResponse<TModel>> = await this.client.search(req);
        if (result.statusCode === 200) {
            if(result.body.hits.hits.length > 0){
                return result.body.hits.hits[0]._source;
            }
            return null;
        } else {
            console.log("Non succesfull call, result:", result);
            return null;
        }
    } catch (error) {
        console.log("Error getting result", error);
        return null;
    }
}

According to intellisense, this should work, _source should be of type TModel.

enter image description here

Unfortunately, no luck:

enter image description here

Am I on the right path to make sure the data object's are correct before updating?

We would like to stick to dynamic mapping and don't define the exact model that is needed. I would assume with this setup it doesn't really matter that an request body contains javascript Object or a typescript type?

1 Answers

Eventually it didn't matter what Object it was, I just had to do the update differently:

async update(index: string, obj: any, id: string): Promise<any> {
    try {
        let req: RequestParams.Update<any> = {
            body: {
                "doc": obj
            },
            index: index,
            id: id
        };
        var result = await this.client.update(req);
        if (result.statusCode === 200 || result.statusCode === 201 || result.statusCode == 202 || result.statusCode == 204) {
            return result.body;
        } else {
            console.log("Non succesfull call, result:", result);
            return null;
        }
    } catch (error) {
        console.error("Error updating", error);
    }
}

So all updates should come within doc and then everything is fine.

Found in this guide: https://hub.packtpub.com/crud-create-read-update-delete-operations-elasticsearch/

Related