Skip to content

Commit

Permalink
Merge pull request #97 from Daseul1/feat/#79
Browse files Browse the repository at this point in the history
[#79]feat:엘라스틱서치
  • Loading branch information
Daseul1 committed Mar 31, 2022
2 parents ed9372a + bbe3873 commit f8e39b3
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 17 deletions.
Binary file modified .DS_Store
Binary file not shown.
13 changes: 13 additions & 0 deletions ars/docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,16 @@ services:
image: redis:6.2.6
ports:
- 6379:6379

elasticsearch:
image: elasticsearch:7.17.0
environment:
discovery.type: single-node
ports:
- 9200:9200

logstash:
image: logstash:7.17.0
volumes:
- ./elk/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
- ./elk/logstash/mysql-connector-java-8.0.28.jar:/usr/share/logstash/mysql-connector-java-8.0.28.jar
13 changes: 13 additions & 0 deletions ars/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,16 @@ services:
image: redis:6.2.6
ports:
- 6379:6379

elasticsearch:
image: elasticsearch:7.17.0
environment:
discovery.type: single-node
ports:
- 9200:9200

logstash:
image: logstash:7.17.0
volumes:
- ./elk/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
- ./elk/logstash/mysql-connector-java-8.0.28.jar:/usr/share/logstash/mysql-connector-java-8.0.28.jar
24 changes: 24 additions & 0 deletions ars/elk/logstash/logstash.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
input {
jdbc {
jdbc_driver_library => "/usr/share/logstash/mysql-connector-java-8.0.28.jar"
jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://my_database:3306/ars"
jdbc_user => "root"
jdbc_password => "3160"
schedule => "* * * * *"

use_column_value => true
tracking_column => "updatedat"
last_run_metadata_path => "./aaa.txt"

tracking_column_type => "numeric"
statement => "select id, title, start_price, instant_bid, price, thumbnail, createdAt, deadline, tag1, tag2, tag3, tag4, updatedat, unix_timestamp(updatedat) as updatedat from art where unix_timestamp(updatedat) > :sql_last_value order by updatedat asc"
}
}

output {
elasticsearch {
hosts => "elasticsearch:9200"
index => "artipul"
}
}
Binary file added ars/elk/logstash/mysql-connector-java-8.0.28.jar
Binary file not shown.
4 changes: 4 additions & 0 deletions ars/src/apis/art/art.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Module } from '@nestjs/common';
import { ElasticsearchModule } from '@nestjs/elasticsearch';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ArtImage } from '../artImage/entities/artImage.entity';
import { Engage } from '../engage/entities/engage.entity';
Expand All @@ -22,6 +23,9 @@ import { LikeArt } from './entities/likeArt.entity';
Payment,
Engage,
]),
ElasticsearchModule.register({
node: 'http://elasticsearch:9200',
}),
],
providers: [
ArtResolver, //
Expand Down
75 changes: 70 additions & 5 deletions ars/src/apis/art/art.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Sse, UseGuards } from '@nestjs/common';
import { UseGuards } from '@nestjs/common';
import { ElasticsearchService } from '@nestjs/elasticsearch';
import { Args, Mutation, Resolver, Query } from '@nestjs/graphql';
import { FileUpload, GraphQLUpload } from 'graphql-upload';
import { GqlAuthAccessGuard } from 'src/common/auth/gql-auth.guard';
Expand All @@ -11,22 +12,76 @@ import { PaymentService } from '../payment/payment.service';
import { ArtService } from './art.service';
import { CreateArtInput } from './dto/createArtInput';
import { Art } from './entities/art.entity';
import { Cache } from 'cache-manager';
import { CACHE_MANAGER, Inject } from '@nestjs/common';

@Resolver()
export class ArtResolver {
constructor(
private readonly artService: ArtService,
private readonly fileService: FileService,
private readonly likeArtService: LikeArtService,
private readonly elasticsearchService: ElasticsearchService,

@Inject(CACHE_MANAGER)
private readonly cacheManager: Cache,
private readonly paymentService: PaymentService,
) {}

@Query(() => [Art])
async fetchArts(
@Args({ name: 'tags', type: () => [String] }) tags: string[],
@Args({ name: 'createdAt', defaultValue: '1970-2-10' }) createdAt: string,
@Args('tag1') tag1: string,
@Args('tag2', { nullable: true }) tag2: string,
@Args('tag3', { nullable: true }) tag3: string,
@Args('tag4', { nullable: true }) tag4: string,
) {
return await this.artService.findAll(tags, createdAt);
// redis에 캐시되어 있는지 확인하기
const redisValue = await this.cacheManager.get(
`tag1: ${tag1}, tag2: ${tag2}, tag3: ${tag3}, tag4: ${tag4}`,
);
if (redisValue) {
console.log(redisValue);
return redisValue;
}

// 레디스에 캐시가 되어있지 않다면, 엘라스틱서치에서 조회하기(유저가 검색한 검색어로 조회하기)
const result = await this.elasticsearchService.search({
index: 'artipul',
query: {
bool: {
should: [
{ match: { tag1: tag1 } },
{ match: { tag2: tag2 } },
{ match: { tag3: tag3 } },
{ match: { tag4: tag4 } },
],
},
},
});

if (!result.hits.hits.length) return null;

const artTags = result.hits.hits.map((el: any) => ({
id: el._source.id,
title: el._source.title,
start_price: el._source.start_price,
instant_bid: el._source.instant_bid,
price: el._source.price,
deadline: el._source.deadline,
tag1: el._source.tag1,
tag2: el._source.tag2,
tag3: el._source.tag3,
tag4: el._source.tag4,
}));

// 엘라스틱서치에서 조회 결과가 있다면, 레디스에 검색결과 캐싱해놓기
await this.cacheManager.set(
`tag1: ${tag1}, tag2: ${tag2}, tag3: ${tag3}, tag4: ${tag4}`,
artTags,
{ ttl: 0 },
);
// 최종 결과 브라우저에 리턴해주기
return artTags;
}

@Query(() => Art)
Expand Down Expand Up @@ -118,10 +173,20 @@ export class ArtResolver {

@UseGuards(GqlAuthAccessGuard)
@Mutation(() => Art)
createArt(
async createArt(
@Args('createArtInput') createArtInput: CreateArtInput, //
@CurrentUser() currentUser: ICurrentUser,
) {
//엘라스틱서치에서 등록할때 한번 사용 후 주석
// const result = await this.elasticsearchService.create({
// id: 'artipulid',
// index: 'artipul',
// document: {
// ...createArtInput,
// currentUser,
// },
// });

return this.artService.create({ ...createArtInput }, currentUser);
}

Expand Down
12 changes: 5 additions & 7 deletions ars/src/apis/art/art.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class ArtService {
}

// 작품 등록
async create({ image_urls, tags, ...rest }, currentUser) {
async create({ image_urls, tag1, tag2, tag3, tag4, ...rest }, currentUser) {
const queryRunner = this.connection.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
Expand All @@ -147,10 +147,10 @@ export class ArtService {
...rest,
user: currentUser,
thumbnail: image_urls[0],
tag1: tags[0],
tag2: tags[1],
tag3: tags[2],
tag4: tags[3],
tag1,
tag2,
tag3,
tag4,
});

for (let i = 0; i < image_urls.length; i++) {
Expand Down Expand Up @@ -185,7 +185,6 @@ export class ArtService {
const result = await queryRunner.manager.count(Engage, {
userId: userId,
});

await queryRunner.commitTransaction();
return result;
} catch (error) {
Expand All @@ -204,7 +203,6 @@ export class ArtService {
const result = await queryRunner.manager.count(LikeArt, {
userId: userId,
});

await queryRunner.commitTransaction();
return result;
} catch (error) {
Expand Down
13 changes: 11 additions & 2 deletions ars/src/apis/art/dto/createArtInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ export class CreateArtInput {
@Field(() => Boolean)
is_soldout: boolean;

@Field(() => [String])
tags: string[];
@Field(() => String)
tag1: string;

@Field(() => String)
tag2: string;

@Field(() => String)
tag3: string;

@Field(() => String)
tag4: string;
}
9 changes: 9 additions & 0 deletions ars/src/apis/art/entities/art.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ManyToOne,
OneToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';

@Entity()
Expand Down Expand Up @@ -58,6 +59,14 @@ export class Art {
@Field(() => Boolean)
is_soldout: boolean;

@UpdateDateColumn()
@Field(() => Date)
updatedAt: Date;

@DeleteDateColumn()
@Field(() => Date)
deletedAt: Date;

@ManyToOne(() => User, { eager: true })
@Field(() => User)
user: User;
Expand Down
1 change: 1 addition & 0 deletions ars/src/apis/pointTransaction/pointTransaction.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export class PointTransactionServive {
status: POINTTRANSACTION_STATUS_ENUM.PAYMENT,
},
);

// 유저 누적 포인트 업데이트
const updatedUser = await queryRunner.manager.save(User, {
...user,
Expand Down
10 changes: 8 additions & 2 deletions ars/src/common/graphql/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type Art {
price: Int!
thumbnail: String!
createdAt: DateTime!
deadline: String!
is_soldout: Boolean!
updatedAt: DateTime!
deletedAt: DateTime!
deadline: DateTime!
is_soldout: Boolean!
Expand Down Expand Up @@ -119,7 +122,7 @@ type Comment {
}

type Query {
fetchArts(tags: [String!]!, createdAt: String = "1970-2-10"): [Art!]!
fetchArts(tag1: String!, tag2: String, tag3: String, tag4: String): [Art!]!
fetchArt(artId: String!): Art!
fetchArtImages(artId: String!): [ArtImage!]!
fetchEngageCount: Float!
Expand Down Expand Up @@ -187,7 +190,10 @@ input CreateArtInput {
deadline: DateTime!
image_urls: [String!]!
is_soldout: Boolean!
tags: [String!]!
tag1: String!
tag2: String!
tag3: String!
tag4: String!
}

"""The `Upload` scalar type represents a file upload."""
Expand Down
2 changes: 1 addition & 1 deletion frontend/payment.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
{
headers: {
Authorization:
"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFhYUBhLmEiLCJzdWIiOiJjNDlhNjc1MS1jMzA3LTQyZmYtYWE5MS1kZDFmYzA4MGNjMzMiLCJpYXQiOjE2NDg1MzIzNDcsImV4cCI6MTY0ODUzNTk0N30.4dRtuBTpWbQbYM6K1aLmcEoHLRKDiuxAQ_hV82J9wVA",
"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImJiYkBhLmEiLCJzdWIiOiI4MzdjZTkyOS1lYjE5LTRiYTgtOTgzNi02ZTk3NTQ2NzkzNGEiLCJpYXQiOjE2NDg2MzU0OTcsImV4cCI6MTY0ODYzOTA5N30.0biQLLvJrSYyntwAsBzQX6abz-x7yXsFDSr44uA7h2M",
},
}
);
Expand Down

0 comments on commit f8e39b3

Please sign in to comment.