기타/관심(●'◡'●)

Qdrant Payload 필터로 원하는 문서만 제거하기

sesam 2025. 8. 18. 17:35
728x90

 

파일 첨부 후 qrant DB 저장이 된다.

여러 파일이 들어가 있을 수도 있는데, 특정 파일만 qrant DB에서 삭제할 수 있는 기능이 필요하다.

 

 

 

Qdrant DB 설정

qrant DB에서 metaData를 통해 필터 기능을 이용해볼 것이다.

Collection 생성할 때 Payload indexes 필드를 어떻게 해야하는지 알아보자.

화면은 Qdrant 컬렉션에서 payload 필드를 인덱싱하는 설정

 

1. Field name

  • 인덱스를 걸고 싶은 payload 키 이름.
  • 여기서는 file_name이라고 해서, 벡터 삽입 시 payload에 들어가는 "file_name": "manual.pdf" 같은 값에 대해 검색 최적화를 하겠다는 뜻이야.

2. Field type

  • 이 필드의 데이터 타입에 맞게 선택하는 옵션.
  • 주요 타입:
    • keyword: 단일 값, 토큰화 없이 완전 일치 검색. (ID, 코드, 짧은 라벨 등)
    • text: 토큰화해서 full-text 검색, 부분 매칭 가능. (문장, 제목, 파일명 같이 문자열 검색)
    • integer/float: 숫자 범위 검색.
    • uuid/datetime/geo/bool: 각각 특수 타입.
  • file_name은 보통 전체 문자열 매치로 쓰고 싶으니 keyword로 해도 되고, 부분 검색(예: manual이 포함된 파일)까지 하고 싶으면 text가 맞아.

3. Tokenizer

  • text 타입일 때만 적용됨. 문자열을 토큰으로 나누는 방법.
  • 옵션:
    • whitespace: 공백 기준으로 쪼갬. "manual.pdf" → "manual.pdf" (사실상 단일 토큰)
    • word: 단어 단위 분리.
    • prefix: 접두어 단위 분리(자동 완성 기능 유사).
  • 파일명은 사실 공백이 거의 없으니 whitespace 쓰면 파일명 전체가 하나의 토큰으로 들어가서 "equals"나 "match" 조건에 잘 맞아.

4. Lowercase

  • 체크하면 모든 문자열을 소문자로 변환해서 저장.
  • "Manual.PDF"와 "manual.pdf"를 같은 걸로 인식하게 해줌.
  • 파일명 검색할 땐 웬만하면 켜두는 게 좋아.

5. Min / Max token length

  • 토큰 필터링 옵션.
  • 예: Min=3 → 세 글자 미만은 무시 (불용어, 짧은 토큰 제거).
  • 파일명 같은 경우 대부분 긴 문자열이라 기본값(빈칸) 두는 게 무난.

 정리

  • file_name을 고유하게 관리하려면 사실 keyword 타입이 더 적합해 → 완전 일치 검색용.
  • text + whitespace를 쓰면 부분 검색도 가능하지만, 파일 삭제 같은 정확 매칭 작업엔 굳이 필요 없음.
  • file_id는 무조건 keyword 타입으로 만드는 게 좋아 (ID는 딱 떨어지는 값이니까).

👉 즉, 지금처럼 text + whitespace로 둬도 동작은 하지만, 삭제/필터 목적이라면 file_id → keyword, file_name → keyword로 해두는 게 가장 깔끔해.

 

 

타입 keyword(권장) 또는 text+lowercase 이게 무슨 차이?

Qdrant에서 Payload 인덱스 타입에 따라 검색/삭제 동작이 달라져. file_name 같은 필드라서 keyword vs text(lowercase)가 헷갈릴 수 있거든.

1. keyword
 - 완전 일치 검색 전용
 - "file_name": "manual.pdf" → equals "manual.pdf" 조건일 때만 매치.
- 토큰 분리 없음 (문자열 전체를 하나의 값으로 취급).
- 속도 빠르고, 삭제/업데이트 같은 “정확한 매칭”에 적합.
- 용도: 파일명, UUID, 코드, 카테고리 라벨 같은 고유 식별자.

2. text (+ lowercase 옵션)
- 토큰화(Text search) 기능. (설정한 tokenizer에 따라 단어, prefix, 공백 등으로 쪼갬)
- "manual.pdf" → "manual", "pdf" 등으로 나뉘어 저장될 수 있음.
- 검색 시 "manual"만 넣어도 매칭 가능 → 부분검색/풀텍스트검색에 유리.
- lowercase 옵션을 켜면 대소문자 구분 없이 검색됨.
- 용도: 문장, 설명, 제목, 태그처럼 부분 검색/풀텍스트 검색을 하고 싶을 때.

3. 차이 요약
타입  검색 방식  장점  단점
keyword  완전 일치만  빠르고 확실함  부분 검색 불가
text+lowercase 부분 검색/단어 검색 "manual"만 쳐도 "manual.pdf" 찾음  삭제 시 “manual”만 주면 의도치 않게 여러 개 지워질 수 있음

 

 파일 삭제용으로는 keyword가 무조건 안전해.

  • file_name = keyword → “manual.pdf”만 정확히 지움.
  • file_name = text → “manual”로만 매치하면 "manual.pdf", "manual_guide.docx" 다 날아갈 수 있음.

👉 즉, 네 케이스처럼 “특정 파일만 지우기”가 목적이라면 keyword 타입을 추천해.
혹시 파일 검색(부분매칭)까지 쓰고 싶으면, file_name=keyword(삭제용) + file_name_search=text(검색용) 이렇게 필드를 따로 두는 방법도 있어.

 

 

 


 

n8n에서 삭제하기

방법1. HTTP 요청으로 삭제하기

 

방법2. Qdrant 설치 후 Qdrant 노드 사용하기 (채택 ✅ )

 방법2-1. point id 직접 지정

    따로 서버를 가지고 있지 않고, 따로 DB를 만들고 싶지 않기 때문에 ponit id를 저장할 곳이 없기 때문에 탈락.

    n8n에서 메모리 DB같은걸 사용할 수 있을 것 같은데, 컨테이너 내리면 어차피 사라지기 때문에, 이건 이용안하기로 함

 

 

 방법2-2. payload filter로 지정 (채택 ✅ )

 

💡 Delete Playload 노드와 Delete Point 노드 중 어떤 것을 사용해야하는가?
1. Delete Points (resource: point / operation: deletePoints) ✅
→ 이게 실제로 포인트(=청크 벡터) 자체를 삭제하는 노드야.
→ 여기에 requestOptions.body에 filter(JSON) 넣으면 "file_name": "manual.txt"인 포인트 전부 지워짐.

{
  "filter": {
    "must": [
      { "key": "file_name", "match": { "value": "manual.txt" } }
    ]
  },
  "wait": true
}​

 
2. Delete Payload (resource: payload / operation: deletePayload) ❌
→ 이건 포인트는 그대로 두고, payload 안의 key-value만 지움.
→ 즉 벡터(청크)는 남아있어서 검색/조회 시 여전히 결과로 튀어나와.
→ 파일 삭제 목적에는 맞지 않아.


3. 정리
“manual.txt 벡터를 통째로 없애고 싶다” → 무조건 Delete Points.
“manual.txt 태그만 떼고 싶다(포인트는 살려둠)” → 그럴 때만 Delete Payload.

 

💡Qdrant 구조 : Point와 Payload




728x90