001/* 002 * (C) Copyright 2019 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Salem Aouana 018 */ 019 020package org.nuxeo.elasticsearch.hint; 021 022import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; 023import org.elasticsearch.index.query.QueryBuilder; 024import org.elasticsearch.index.query.QueryBuilders; 025import org.nuxeo.ecm.core.api.repository.RepositoryManager; 026import org.nuxeo.ecm.core.query.sql.model.EsHint; 027import org.nuxeo.elasticsearch.api.ESHintQueryBuilder; 028import org.nuxeo.elasticsearch.api.ElasticSearchAdmin; 029import org.nuxeo.runtime.api.Framework; 030 031/** 032 * The implementation of {@link ESHintQueryBuilder} for the <strong>"more_like_this"</strong> Elasticsearch hint 033 * operator. 034 * 035 * @since 11.1 036 */ 037public class MoreLikeThisESHintQueryBuilder implements ESHintQueryBuilder { 038 039 public static final int MORE_LIKE_THIS_MIN_TERM_FREQ = 1; 040 041 public static final int MORE_LIKE_THIS_MIN_DOC_FREQ = 3; 042 043 public static final int MORE_LIKE_THIS_MAX_QUERY_TERMS = 12; 044 045 /** 046 * {@inheritDoc} 047 * <p> 048 * 049 * @return {@link org.elasticsearch.index.query.MoreLikeThisQueryBuilder} 050 */ 051 @Override 052 public QueryBuilder make(EsHint hint, String fieldName, Object value) { 053 String[] indexFields = hint.getIndexFieldNames(); 054 String[] fields = indexFields.length > 0 ? indexFields : new String[] { fieldName }; 055 return QueryBuilders.moreLikeThisQuery(fields, null, getItems(value)) 056 .analyzer(hint.analyzer) 057 .minDocFreq(MORE_LIKE_THIS_MIN_DOC_FREQ) 058 .minTermFreq(MORE_LIKE_THIS_MIN_TERM_FREQ) 059 .maxQueryTerms(MORE_LIKE_THIS_MAX_QUERY_TERMS); 060 } 061 062 /** 063 * Build a single or an array of {@link MoreLikeThisQueryBuilder.Item} according to the value type. Where each 064 * {@link MoreLikeThisQueryBuilder.Item} represent a document request 065 * 066 * @param value represent what we are looking for. Can be <code>String</code> or an array of <code>String</code> 067 * @return the items / document requests 068 */ 069 public static MoreLikeThisQueryBuilder.Item[] getItems(Object value) { 070 RepositoryManager rm = Framework.getService(RepositoryManager.class); 071 String repo = rm.getDefaultRepository().getName(); 072 ElasticSearchAdmin esa = Framework.getService(ElasticSearchAdmin.class); 073 String esIndex = esa.getIndexNameForRepository(repo); 074 Object[] values; 075 if (value instanceof Object[]) { 076 values = (Object[]) value; 077 } else { 078 values = new Object[] { value }; 079 } 080 MoreLikeThisQueryBuilder.Item[] ret = new MoreLikeThisQueryBuilder.Item[values.length]; 081 for (int i = 0; i < values.length; i++) { 082 ret[i] = new MoreLikeThisQueryBuilder.Item(esIndex, (String) values[i]); 083 } 084 return ret; 085 } 086}