본문 바로가기

Elasticsearch

[elasticsearch] dis_max란 무엇인지 알아보기, 실습하기 (bool, must와 함께 쓰기)

반응형

dis_max

정확한 일치하는 문서에 더 높은 점수를 주기 위한 방법  - dis_max(DisjunctionMaxQuery에서 따온 용어)

dis_max는 멀티 키워드 검색할 때, 여러 필드에서 검색 수행 시 멀티 키워드의 키워드와 동일한 키워드의 score에 더욱 높은 점수를 주는 방식이다. (하지만 반전이 있었으니...)

 

 

실습해보기

 

dis_max_test 라는 인덱스 생성 

PUT dis_max_test
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "description": {
        "type": "text"
      }
    }
  }
}

 

데이터 입력

POST dis_max_test/_doc
{
  "title": "Autobiography of Osho",
  "description": "A professor of philosophy, he travelled throughout India during the 1960s as a public speaker. His outspoken criticism of politicians and the political mind, Mahatma Gandhi and institutionalised religion made him controversial."
}

POST dis_max_test/_doc
{
  "title": "Osho philosophy",
  "description": "Osho Autobiography is a book on philosophy. Osho travelled throughout India during the 1960s as a public speaker. Osho outspoken criticism of politicians and the political mind, Mahatma Gandhi and institutionalised religion made him controversial.Osho written many books on philosophy."
}

 

조회해보기

GET dis_max_test/_search
{
  "query": {
    "bool": {
      "should": [
          {
            "match": {
              "title": "Osho Autobiography"
            }
          },
          {
            "match": {
            "ddscription": "Osho Autobiography"
          }
        }
        ]
    }
  }
}

아래 순서대로 값이 나왔다. 

  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.9254787,
    "hits" : [
      {
        "_index" : "dis_max_test",
        "_type" : "_doc",
        "_id" : "SM4FtYIBnZsIFAhk2vJA",
        "_score" : 1.9254787,
        "_source" : {
          "title" : "Osho philosophy",
          "description" : "Osho Autobiography is a book on philosophy. Osho travelled throughout India during the 1960s as a public speaker. Osho outspoken criticism of politicians and the political mind, Mahatma Gandhi and institutionalised religion made him controversial.Osho written many books on philosophy."
        }
      },
      {
        "_index" : "dis_max_test",
        "_type" : "_doc",
        "_id" : "Sc4FtYIBnZsIFAhk3_J2",
        "_score" : 0.80925685,
        "_source" : {
          "title" : "Autobiography of Osho",
          "description" : "A professor of philosophy, he travelled throughout India during the 1960s as a public speaker. His outspoken criticism of politicians and the political mind, Mahatma Gandhi and institutionalised religion made him controversial."
        }
      }
    ]
  }



bool query가 should 안에 있는 쿼리들을 수행하고 점수를 모두 합한다. 각 매칭되는 절의 수를 곱하고 전체 매칭된 절의 수로 나눈다. 이렇게 계산된 스코어로 위와 같이 정렬되었다. 

 

title = "Osho philosophy" 인 도큐먼트에 "Osho Autobiography" 도 존재하고 "Osho"도 여러개 더 존재한다. 여기서 title이 Autobiography of Osho에 더 많은 점수를 주고 싶을 때 dis_max를 사용하고 아래와 같은 쿼리를 날리면 그게 가능하다고 하는데..

 

GET dis_max_test/_search
{
  "query": {
    "bool": {
      "must": {
      "dis_max": {
      "queries": [
        {
          "match": {
            "title": "Osho Autobiography"
          }
        },
        {
          "match": {
            "description": "Osho Autobiography"
          }
        }
        ]
    }   
      }
    }
  }
}

dis_max를 사용하지 않은 쿼리와 같은 결과가 조회된다. 스코어는 아주 살짝 다르지만..

 

 

이후에도 dis_max사용 시의 차이를 알아보려고 한국어로 데이터를 넣어보기도 하고 했지만 결국 차이가 없었다. 스코어가 살짝 달라졌지만 그 차이가 너무 소소해서 그런지 결과가 달라지진않았다. dis_max 내용을 실제로 구현해본 블로거의 내용은 2015년도라 아마 es 버전에 따라 조금씩 점수 알고리즘이 다른 것 같다. 이제 dis_max는 굳이 안써도 되는 기능이 된 것인가....? Elasticsearch v8 도큐먼트에 dis_max의 내용이 있기는 하지만 너무 짧고 "match"없이 "term" 만 있는 걸로 보아 term 만 가능한건가.. 

 

 

 

만약 dis_max를 쓴 경우의 차이가 명확한 경우가 있다면 댓글로 알려주시면 감사하겠습니다. 🐥

 

 

 


 

 

 

일반적인 Disjunction max query 

GET /_search
{
  "query": {
    "dis_max": {
      "queries": [
        { "term": { "title": "Quick pets" } },
        { "term": { "body": "Quick pets" } }
      ],
      "tie_breaker": 0.7
    }
  }
}

 

bool 과 dis_max를 함께 쓴 query

{
    query: {
      bool: {
        must: {
          dis_max: {
            queries: [
              {
                match: {
                  name: 'TEMP',
                },
              },
              {
                match: {
                  categories: search,  // search = 검색한 입력어
                },
              },
              {
              	multi_match: {},
              },  
            ],
          },
        },
        filter: {
          geo_distance: {
            distance: `${radius}m`,
            location: placeLocation,
            distance_type: 'arc',  // default : arc
          },
        },
      },
    },
   },
}

 

 

 

Reference : 

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-dis-max-query.html

https://self-learning-java-tutorial.blogspot.com/2015/12/elasticsearch-java-dis-max-query.html

반응형