Home > Enterprise >  id field is missing from search result in elasticsearch
id field is missing from search result in elasticsearch

Time:05-02

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!

  • Related