기본 콘텐츠로 건너뛰기

[ SOLR ] DataImport 처리할 때 주의할 점.



  Solr 에 외부 데이터를 Import 할 때 사용하는 것이 DataImport 패키지다. Solr 를 다운로드하면 존재하는 별도의 라이브러리로 Solr 에서 Batch Import 역할을 담당한다. 다양한 데이터 소스로 부터 데이터를 처리하는 방법을 제공하고 있기 때문에 실제 적용할 때는 관련된 Wiki 정보를 확인해 보면 된다.

  Solr 에서 자체적으로 제공하는 UpdateHandler 와는 다르게 동작하는 것으로 파악이 된다. 즉, UpdateHandler에서 처리하는 Chain 들의 처리를 DataImport에서 따로 설정해서 처리를 하여야 한다는 점이다. 이런 처리를 수행할 때 주의할 점이 존재한다.

  데이터를 가져올 특정 테이블에 HTML 태그들을 포함하는 "content" 컬럼이 존재할 경우에 이를 가져와서 HTML 이 존재하는 정보 (원본 데이터 그대로) 화 HTML 이 제거된 정보를 사용하여야 하는 경우라면 아래와 같이 설정을 하여 처리를 하게 된다.

<dataConfig>
    <dataSource type="JdbcDataSource" name="ds-1" driver="com.mysql.jdbc.Driver" 
        url="DB 연결 문자열"
        batchSize="-1"
        user="사용자 아이디"
        password="사용자 비밀번호" />        
    <document>
        <entity name="Entity이름"
            pk="id"
            transformer="TemplateTransformer, HTMLStripTransformer"
            query="SELECT * from 대상테이블">
            ...
            <field column="content"  name="content_plain" stripHTML="true" />
            <field column="content"  name="content_html"  stripHTML="false" />
            ...
            <field column="id"       name="id"            template="${entity명.컬럼명1}-${entity명.컬럼명2}-${entity명.컬럼명3}" />

            <!-- SQL 의 SUB Query와 같이 Entity를 Sub document 로 처리하고 doc_id를 지정하면 된다. -->
            <entity name="서브Entity이름"
                transformer="HTMLStripTransformer"
                query="select * FROM 서브테이블">
                ...
                <field column="description"  name="content_plain" stripHTML="true" />
                <field column="description2" name="content_html"  stripHTML="false" />
                ...
            </entity>
        </entity>
    </document>
</dataConfig>

  위의 예제는 Master - Detail 구조의 테이블에서 데이터를 가져와서 처리하는 것이다. 단, RDB에서는 Master-Detail 구조일지라도 Solr 의 Entity로 처리하기 위해서는 Flat 구조의 레코드로 구성해야 하기 때문에 content_plain, content_html 에 MultiValued 구성을 하였고, Unique 를 보장하기 위해서 컬럼1 + 컬럼2 + 컬럼3 의 템플릿을 구성하여 Solr Document 의 Key를 구성하고 있는 것이다.

  위의 예에서 문제가 될 수 있는 부분이 동일한 컬럼인 "Content" 를 가지고 stripHTML Transform을 true/false 로 활용하는 부분이다. 이 처리는 내부적으로 첫번째 처리되는 Transformer의 결과가 관리되고 있는 컬럼의 실제 값으로 치환이 되기 때문에 두번째 동작하는 Transformer는 이미 변경된 컬럼 값을 가지고 동작하게 된다는 것이다. (이 처리는 UpdateHandler에서 Chain 처리와 동일하게 동작한다고 생각하면 된다)

  따라서 결과적으로 content_plain 필드의 처리를 위해서 Strip HTML 처리를 한 결과가 content 컬럼의 값으로 갱신이 되었기 때문에 두 번째인 content_html 은 HTML 태그가 존재하는 원본 데이터이기를 예상하지만 실제 처리 결과는 이미 HTML 태그가 제거된 값으로 처리된다. 따라서 content_plain 과 content_html 은 동일한 값을 가지게 된다.

  순서를 바꿔서 하면 될 듯 하지만 동일한 컬럼에 대해서 동일한 Transformer 가 처리되는 것과 동일하기 때문에 두 번째는 무시되는 상황이 발생한다. true/false 가 다르므로 제대도 동작할 것이라고 판단했지만, 실제 처리 결과는 두 번째가 무시된 결과로 두 필드가 모두 HTML 태그를 포함한 값으로 나온다.

  이를 해결하는 방법은 서브 Entity 처리에서 보이는 것과 같이 컬럼을 다르게 하여 Transformer 를 적용하면 해결이 된다. 서로 다른 컬럼인 경우는 각자 처리가 되기 때문이다. 그러나 이렇게 하는 경우는 대량의 데이터를 처리할 경우에 성능에 문제가 발생한다.

댓글