فهرست منبع

fix #1733 learning to rank support

Shinsuke Sugaya 7 سال پیش
والد
کامیت
994af1bcd7

+ 11 - 5
src/main/java/org/codelibs/fess/es/client/FessEsClient.java

@@ -159,6 +159,7 @@ import org.slf4j.LoggerFactory;
 
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
 import com.google.common.io.BaseEncoding;
 import com.google.common.io.BaseEncoding;
 
 
 public class FessEsClient implements Client {
 public class FessEsClient implements Client {
@@ -219,8 +220,12 @@ public class FessEsClient implements Client {
     }
     }
 
 
     public void addTransportAddress(final String host, final int port) {
     public void addTransportAddress(final String host, final int port) {
+        transportAddressList.add(new TransportAddress(getInetAddressByName(host), port));
+    }
+
+    protected InetAddress getInetAddressByName(final String host) {
         try {
         try {
-            transportAddressList.add(new TransportAddress(InetAddress.getByName(host), port));
+            return InetAddress.getByName(host);
         } catch (final UnknownHostException e) {
         } catch (final UnknownHostException e) {
             throw new FessSystemException("Failed to resolve the hostname: " + host, e);
             throw new FessSystemException("Failed to resolve the hostname: " + host, e);
         }
         }
@@ -269,10 +274,11 @@ public class FessEsClient implements Client {
                 });
                 });
                 runner.build(config);
                 runner.build(config);
             }
             }
-            client = runner.client();
-            addTransportAddress("localhost", runner.node().settings().getAsInt("transport.tcp.port", 9300));
+            final int port = runner.node().settings().getAsInt("transport.tcp.port", 9300);
+            client = createTransportClient(fessConfig, Lists.newArrayList(new TransportAddress(getInetAddressByName("localhost"), port)));
+            addTransportAddress("localhost", port);
         } else {
         } else {
-            client = createTransportClient(fessConfig);
+            client = createTransportClient(fessConfig, transportAddressList);
         }
         }
 
 
         if (StringUtil.isBlank(transportAddressesValue)) {
         if (StringUtil.isBlank(transportAddressesValue)) {
@@ -346,7 +352,7 @@ public class FessEsClient implements Client {
         });
         });
     }
     }
 
 
-    protected Client createTransportClient(final FessConfig fessConfig) {
+    protected Client createTransportClient(final FessConfig fessConfig, final List<TransportAddress> transportAddressList) {
         final Builder settingsBuilder = Settings.builder();
         final Builder settingsBuilder = Settings.builder();
         settingsBuilder.put("cluster.name", fessConfig.getElasticsearchClusterName());
         settingsBuilder.put("cluster.name", fessConfig.getElasticsearchClusterName());
         settingsBuilder.put("client.transport.sniff", fessConfig.isElasticsearchTransportSniff());
         settingsBuilder.put("client.transport.sniff", fessConfig.isElasticsearchTransportSniff());

+ 17 - 6
src/main/java/org/codelibs/fess/es/query/StoredLtrQueryBuilder.java

@@ -1,3 +1,18 @@
+/*
+ * Copyright 2012-2018 CodeLibs Project and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
 package org.codelibs.fess.es.query;
 package org.codelibs.fess.es.query;
 
 
 import java.io.IOException;
 import java.io.IOException;
@@ -6,7 +21,6 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Objects;
 
 
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Query;
-import org.elasticsearch.Version;
 import org.elasticsearch.common.ParseField;
 import org.elasticsearch.common.ParseField;
 import org.elasticsearch.common.io.stream.NamedWriteable;
 import org.elasticsearch.common.io.stream.NamedWriteable;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.io.stream.StreamOutput;
@@ -54,9 +68,7 @@ public class StoredLtrQueryBuilder extends AbstractQueryBuilder<StoredLtrQueryBu
         out.writeOptionalString(modelName);
         out.writeOptionalString(modelName);
         out.writeOptionalString(featureSetName);
         out.writeOptionalString(featureSetName);
         out.writeMap(params);
         out.writeMap(params);
-        if (out.getVersion().onOrAfter(Version.V_6_2_4)) {
-            out.writeOptionalStringArray(activeFeatures != null ? activeFeatures.toArray(new String[0]) : null);
-        }
+        out.writeOptionalStringArray(activeFeatures != null ? activeFeatures.toArray(new String[0]) : null);
         out.writeOptionalString(storeName);
         out.writeOptionalString(storeName);
     }
     }
 
 
@@ -84,8 +96,7 @@ public class StoredLtrQueryBuilder extends AbstractQueryBuilder<StoredLtrQueryBu
 
 
     @Override
     @Override
     protected Query doToQuery(QueryShardContext context) throws IOException {
     protected Query doToQuery(QueryShardContext context) throws IOException {
-        // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException("Query processing is not supported.");
     }
     }
 
 
     @Override
     @Override

+ 5 - 8
src/main/java/org/codelibs/fess/helper/QueryHelper.java

@@ -55,10 +55,10 @@ import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
 import org.codelibs.fess.entity.GeoInfo;
 import org.codelibs.fess.entity.QueryContext;
 import org.codelibs.fess.entity.QueryContext;
 import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
 import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
-import org.codelibs.fess.es.query.StoredLtrQueryBuilder;
 import org.codelibs.fess.exception.InvalidQueryException;
 import org.codelibs.fess.exception.InvalidQueryException;
 import org.codelibs.fess.mylasta.action.FessUserBean;
 import org.codelibs.fess.mylasta.action.FessUserBean;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.mylasta.direction.FessConfig;
+import org.codelibs.fess.score.QueryRescorer;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.ComponentUtil;
 import org.dbflute.optional.OptionalThing;
 import org.dbflute.optional.OptionalThing;
 import org.elasticsearch.action.search.SearchRequestBuilder;
 import org.elasticsearch.action.search.SearchRequestBuilder;
@@ -70,7 +70,6 @@ import org.elasticsearch.index.query.RangeQueryBuilder;
 import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder.FilterFunctionBuilder;
 import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder.FilterFunctionBuilder;
 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
-import org.elasticsearch.search.rescore.QueryRescorerBuilder;
 import org.elasticsearch.search.rescore.RescorerBuilder;
 import org.elasticsearch.search.rescore.RescorerBuilder;
 import org.elasticsearch.search.sort.SortBuilder;
 import org.elasticsearch.search.sort.SortBuilder;
 import org.elasticsearch.search.sort.SortBuilders;
 import org.elasticsearch.search.sort.SortBuilders;
@@ -130,7 +129,7 @@ public class QueryHelper {
 
 
     protected List<FilterFunctionBuilder> boostFunctionList = new ArrayList<>();
     protected List<FilterFunctionBuilder> boostFunctionList = new ArrayList<>();
 
 
-    protected List<RescorerBuilder<?>> rescorerList = new ArrayList<>();
+    protected List<QueryRescorer> queryRescorerList = new ArrayList<>();
 
 
     @PostConstruct
     @PostConstruct
     public void init() {
     public void init() {
@@ -954,12 +953,10 @@ public class QueryHelper {
     }
     }
 
 
     public RescorerBuilder<?>[] getRescorers(final Map<String, Object> params) {
     public RescorerBuilder<?>[] getRescorers(final Map<String, Object> params) {
-        rescorerList.clear();
-        rescorerList.add(new QueryRescorerBuilder(new StoredLtrQueryBuilder().modelName("model_6").params(params)).windowSize(100));
-        return rescorerList.toArray(new RescorerBuilder<?>[rescorerList.size()]);
+        return queryRescorerList.stream().map(r -> r.evaluate(params)).toArray(n -> new RescorerBuilder<?>[n]);
     }
     }
 
 
-    public void addRescorer(final RescorerBuilder<?> rescorer) {
-        rescorerList.add(rescorer);
+    public void addQueryRescorer(final QueryRescorer rescorer) {
+        queryRescorerList.add(rescorer);
     }
     }
 }
 }

+ 42 - 0
src/main/java/org/codelibs/fess/score/LtrQueryRescorer.java

@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012-2018 CodeLibs Project and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.codelibs.fess.score;
+
+import java.util.Map;
+
+import org.codelibs.fess.es.query.StoredLtrQueryBuilder;
+import org.elasticsearch.search.rescore.QueryRescorerBuilder;
+import org.elasticsearch.search.rescore.RescorerBuilder;
+
+public class LtrQueryRescorer implements QueryRescorer {
+
+    protected String modelName;
+
+    protected int windowSize = 100;
+
+    @Override
+    public RescorerBuilder<?> evaluate(Map<String, Object> params) {
+        return new QueryRescorerBuilder(new StoredLtrQueryBuilder().modelName(modelName).params(params)).windowSize(windowSize);
+    }
+
+    public void setModelName(String modelName) {
+        this.modelName = modelName;
+    }
+
+    public void setWindowSize(int windowSize) {
+        this.windowSize = windowSize;
+    }
+}

+ 24 - 0
src/main/java/org/codelibs/fess/score/QueryRescorer.java

@@ -0,0 +1,24 @@
+/*
+ * Copyright 2012-2018 CodeLibs Project and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.codelibs.fess.score;
+
+import java.util.Map;
+
+import org.elasticsearch.search.rescore.RescorerBuilder;
+
+public interface QueryRescorer {
+    RescorerBuilder<?> evaluate(final Map<String, Object> params);
+}

+ 5 - 1
src/main/java/org/codelibs/fess/util/QueryResponseList.java

@@ -142,7 +142,7 @@ public class QueryResponseList implements List<Map<String, Object>> {
     }
     }
 
 
     private Map<String, Object> parseSearchHit(final FessConfig fessConfig, final String hlPrefix, final SearchHit searchHit) {
     private Map<String, Object> parseSearchHit(final FessConfig fessConfig, final String hlPrefix, final SearchHit searchHit) {
-        final Map<String, Object> docMap = new HashMap<>();
+        final Map<String, Object> docMap = new HashMap<>(32);
         if (searchHit.getSourceAsMap() == null) {
         if (searchHit.getSourceAsMap() == null) {
             searchHit.getFields().forEach((key, value) -> {
             searchHit.getFields().forEach((key, value) -> {
                 docMap.put(key, value.getValue());
                 docMap.put(key, value.getValue());
@@ -188,6 +188,10 @@ public class QueryResponseList implements List<Map<String, Object>> {
         if (!docMap.containsKey(Constants.SCORE)) {
         if (!docMap.containsKey(Constants.SCORE)) {
             docMap.put(Constants.SCORE, searchHit.getScore());
             docMap.put(Constants.SCORE, searchHit.getScore());
         }
         }
+
+        if (!docMap.containsKey(fessConfig.getIndexFieldId())) {
+            docMap.put(fessConfig.getIndexFieldId(), searchHit.getId());
+        }
         return docMap;
         return docMap;
     }
     }
 
 

+ 10 - 0
src/main/resources/app.xml

@@ -110,6 +110,16 @@
 		<postConstruct name="addHighlightField">
 		<postConstruct name="addHighlightField">
 			<arg>"content"</arg>
 			<arg>"content"</arg>
 		</postConstruct>
 		</postConstruct>
+		<!--
+		<postConstruct name="addQueryRescorer">
+			<arg>
+				<component class="org.codelibs.fess.score.LtrQueryRescorer">
+					<property name="modelName">"model_6"</property>
+					<property name="windowSize">100</property>
+				</component>
+			</arg>
+		</postConstruct>
+		-->
 	</component>
 	</component>
 	<component name="viewHelper" class="org.codelibs.fess.helper.ViewHelper">
 	<component name="viewHelper" class="org.codelibs.fess.helper.ViewHelper">
 		<postConstruct name="addFacetQueryView">
 		<postConstruct name="addFacetQueryView">