I'm using Elasticsearch v8.1.3 and @elastic/elasticsearch ^8.1.0, @nestjs/elasticsearch ^8.1.0. Tried to implement a simple search functionality like this:
interface PostSearchBody {
id: number,
title: string,
content: string,
authorId: number
}
interface PostSearchResult {
hits: {
total: number;
hits: Array<{
_source: PostSearchBody;
}>;
};
}
// class PostsSearchService
async indexPost(post: Post) {
return this.elasticsearchService.index<PostSearchResult, PostSearchBody>({
index: this.index,
body: {
id: post.id,
title: post.title,
content: post.content,
authorId: post.author.id
}
})
}
async search(text: string) {
const { body } = await this.elasticsearchService.search<PostSearchResult>({
index: this.index,
body: {
query: {
multi_match: {
query: text,
fields: ['title', 'content']
}
}
}
})
const hits = body.hits.hits;
return hits.map((item) => item._source);
}
// class PostsService
async createPost(post: CreatePostDto, user: User) {
const newPost = await this.postsRepository.create({
...post,
author: user
});
await this.postsRepository.save(newPost);
this.postsSearchService.indexPost(newPost);
return newPost;
}
async searchForPosts(text: string) {
const results = await this.postsSearchService.search(text);
// result item should contain "id" field, but doesn't :(
const ids = results.map(result => result.id);
if (!ids.length) {
return [];
}
return this.postsRepository
.find({
where: { id: In(ids) }
});
}
In the searchForPosts
function, a result item should contain "id" field I believe, but it doesn't.
Is this an issue from upgraded elasticsearch version or am I doing something wrong?
CodePudding user response:
Found out what's wrong in there and figured it out.
Above example is originally from here and id
was not being fed to the index function:
async createPost(post: CreatePostDto, user: User) {
// await is not meaningful in the below line:
const newPost = await this.postsRepository.create({
...post,
author: user
});
// you need to use the result of saving transaction
await this.postsRepository.save(newPost);
this.postsSearchService.indexPost(newPost);
return newPost;
}
So it should be:
async createPost(post: CreatePostDto, user: User) {
const newPost = this.postsRepository.create({
...post,
author: user
});
const savedPost = await this.postsRepository.save(newPost);
this.postsSearchService.indexPost(savedPost);
return savedPost;
}
Now it works as expected!