Django에서 PostgreSQL 텍스트 검색

4653 단어 pythondjangopostgres
College Conductor은 교육 컨설턴트와 카운슬러가 수천 개의 미국 대학 정보에 액세스할 수 있도록 합니다. 이러한 학교를 찾는 가장 자연스러운 방법은 검색입니다. College Conductor는 Django 최신 버전을 유지하고 있기 때문에 Django ORM에 노출된 PostgreSQLfull text search을 사용하여 검색을 추가할 수 있었습니다. 검색 기능은 완벽하지 않지만 결과를 신속하게 제공하고 Elasticsearch와 같은 보다 표적화된 도구를 가져오는 것을 방지합니다. 이 포스트에서는 이러한 Django 기능을 사용할 때의 장점과 단점을 다룰 것입니다.

College Conductor의 검색 기능은 대학 이름 검색을 중심으로 합니다. 즉, 데이터에는 몇 가지 흥미로운 특성이 있습니다.
  • 모든 검색 결과는 University of Virginia 또는 Johns Hopkins University와 같은 문구에 표시됩니다.
  • 많은 비율의 용어가 검색하기에 실제로 쓸모가 없습니다(예: University, College).

  • Django가 PostgreSQL에서 노출하는 검색 옵션을 검토했을 때 두 가지 합리적인 접근 방식, 즉 전체 텍스트 검색과 트라이그램 유사성을 찾았습니다.

    먼저 내가 선택하지 않은 것을 봅시다.

    트라이그램 유사성



    트라이그램 유사성은 데이터를 3개의 문자 그룹으로 청크업하여 작동합니다. 일부 계산을 사용하여 PosgreSQL은 트라이그램을 비교하고 결과가 어떠해야 하는지 추론을 시도할 수 있습니다. 이 기술은 오타(때로는 "퍼지 매칭"이라고도 함)를 해결하는 데 유용합니다. 예를 들어, 과일을 검색하고 appel 를 입력하는 경우 트라이그램 검색은 apple 의 예상 결과를 찾습니다.

    불행히도, 나는 트라이그램이 긴 구에 대해 눈에 띄게 실패했다는 것을 발견했습니다. 퍼지 매칭이라는 아이디어가 마음에 들어서 트라이그램 옵션으로 시작했습니다. 기능을 테스트했을 때 전혀 작동하지 않았습니다. VriginiaUniversity of Virginia를 찾지 못할 뿐만 아니라 Virginia를 검색해도 학교를 찾지 못합니다. 저는 이 실패가 학교의 전체 이름이 너무 많이 누락되었기 때문에 발생했다고 생각합니다. Massachusetts 철자를 잘못 입력하여 이익을 얻기 위해 Massachustets College of Pharmacy and Health Sciences를 입력하고 싶은 사람은 누구입니까? 답: 아무도 없습니다.

    옵션 2를 시도해 보겠습니다.

    전체 텍스트 검색



    전체 텍스트 검색을 위한 합리적인 솔루션을 얻는 것은 까다로웠습니다. 다시 말하지만, 문구는 번거로운 것으로 판명되었습니다. 어떤 수준의 성공을 위해 검색 쿼리를 부분으로 나누고 OR 연산자와 함께 결합해야 했습니다. 이 접근 방식을 취함으로써 트라이그램 버전에서 피할 수 없었던 세분성 문제를 피할 수 있었습니다.

    쿼리 세트를 빌드하는 코드는 다음과 같습니다.

    # `search` is the user's provided search string.
    terms = [SearchQuery(term) for term in search.split()]
    # `name` is where the name of the school is stored in the model.
    vector = SearchVector('name')
    query = functools.reduce(operator.or_, terms)
    queryset = queryset.annotate(
        rank=SearchRank(vector, query)).order_by('-rank')
    queryset = queryset.filter(rank__gte=0.04)
    

    OR 연산자와 함께 이 조인 전략을 사용하면 하나의 추가 장애가 있었습니다. 검색 구문과 아무 관련이 없는 것으로 나타날 수 있는 수준의 정크 결과가 있었습니다.

    결과에는 쿼리에 대한 일치 정도를 측정하는 순위 주석이 포함됩니다. 순위를 조사한 결과 모든 정크가 숫자 임계값 미만인 것으로 나타났습니다. 미국 학교 목록은 매우 드물게 변경되기 때문에 임계값(0.04에 가까움) 미만의 모든 것을 잘라내기로 결정했습니다. 데이터 세트가 자주 변경된다면 나는 이 마법의 숫자를 믿지 않을 것입니다. 하지만 내 데이터 세트의 변하지 않는 특성으로부터 이점을 얻을 수 있습니다.

    이 검색 방법에는 여전히 문제가 있습니다.
  • 트라이그램은 검색의 일부가 아니므로 용어의 철자가 정확하지 않으면 결과가 나타나지 않습니다. 그거 짜증나네.
  • 부분 검색도 마찬가지로 유효하지 않습니다. 예를 들어, Virg를 검색하면 결과를 찾을 수 없습니다. 또한 짜증나.

  • 장기적으로 PostgreSQL 전체 텍스트 검색은 College Conductor에게 남아 있지 않을 것이라고 생각합니다. 그러나 단기적으로는 괜찮은 검색 기능을 저렴하게 얻기 위한 훌륭한 선택입니다.

    이 기사는 mattlayman.com 에 처음 등장했습니다.

    좋은 웹페이지 즐겨찾기