Merge pull request #340 from yfujita/master

suggest es 2.0 support. add suggest job	.
This commit is contained in:
yfujita 2015-11-09 23:50:01 +09:00
commit d923beb6e1
10 changed files with 467 additions and 97 deletions

View file

@ -68,10 +68,7 @@ public class SuggestApiManager extends BaseApiManager {
final SuggestResponse suggestResponse = builder.execute().getResponse();
buf.append("\"result\":{");
// TODO removed?
// buf.append("\"index\":\"").append(suggestResponse.getIndex()).append('\"');
buf.append(",\"took\":\"").append(suggestResponse.getTookMs()).append('\"');
buf.append("\"took\":\"").append(suggestResponse.getTookMs()).append('\"');
buf.append(",\"total\":\"").append(suggestResponse.getTotal()).append('\"');

View file

@ -0,0 +1,137 @@
package org.codelibs.fess.exec;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.fess.Constants;
import org.codelibs.fess.crawler.client.EsClient;
import org.codelibs.fess.es.client.FessEsClient;
import org.codelibs.fess.helper.SuggestHelper;
import org.codelibs.fess.util.ComponentUtil;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import org.lastaflute.di.core.SingletonLaContainer;
import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class SuggestCreater implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(Crawler.class);
@Resource
public FessEsClient fessEsClient;
protected static class Options {
@Option(name = "-s", aliases = "--sessionId", metaVar = "sessionId", usage = "Session ID")
protected String sessionId;
@Option(name = "-n", aliases = "--name", metaVar = "name", usage = "Name")
protected String name;
protected Options() {
// noghing
}
}
public static void main(final String[] args) {
final Options options = new Options();
final CmdLineParser parser = new CmdLineParser(options);
try {
parser.parseArgument(args);
} catch (final CmdLineException e) {
System.err.println(e.getMessage()); // NOPMD
System.err.println("java " + Crawler.class.getCanonicalName() // NOPMD
+ " [options...] arguments...");
parser.printUsage(System.err);
return;
}
final String transportAddresses = System.getProperty(Constants.FESS_ES_TRANSPORT_ADDRESSES);
if (StringUtil.isNotBlank(transportAddresses)) {
System.setProperty(EsClient.TRANSPORT_ADDRESSES, transportAddresses);
}
final String clusterName = System.getProperty(Constants.FESS_ES_CLUSTER_NAME);
if (StringUtil.isNotBlank(clusterName)) {
System.setProperty(EsClient.CLUSTER_NAME, clusterName);
}
int exitCode;
try {
SingletonLaContainerFactory.setConfigPath("app.xml");
SingletonLaContainerFactory.init();
final Thread shutdownCallback = new Thread("ShutdownHook") {
@Override
public void run() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying LaContainer..");
}
SingletonLaContainerFactory.destroy();
}
};
Runtime.getRuntime().addShutdownHook(shutdownCallback);
exitCode = process(options);
} catch (final Throwable t) { // NOPMD
logger.error("Suggest creater does not work correctly.", t);
exitCode = Constants.EXIT_FAIL;
} finally {
SingletonLaContainerFactory.destroy();
}
logger.info("Finished suggestCreater.");
System.exit(exitCode);
}
private static int process(final Options options) {
final SuggestCreater creater = SingletonLaContainer.getComponent(SuggestCreater.class);
final LocalDateTime startTime = LocalDateTime.now();
int ret = creater.create();
if (ret == 0) {
ret = creater.purge(startTime);
}
return ret;
}
private int create() {
logger.info("Start create suggest document.");
final AtomicInteger result = new AtomicInteger(1);
final CountDownLatch latch = new CountDownLatch(1);
final SuggestHelper suggestHelper = ComponentUtil.getSuggestHelper();
suggestHelper.indexFromDocuments(ret -> {
logger.info("Success index from documents.");
result.set(0);
latch.countDown();
}, t -> {
logger.error("Failed to update suggest index.", t);
latch.countDown();
});
try {
latch.await();
} catch (InterruptedException ignore) {}
return result.get();
}
private int purge(LocalDateTime time) {
final SuggestHelper suggestHelper = ComponentUtil.getSuggestHelper();
try {
suggestHelper.purge(time);
return 0;
} catch (Exception e) {
logger.info("Purge error.", e);
return 1;
}
}
}

View file

@ -15,10 +15,11 @@
*/
package org.codelibs.fess.helper;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
@ -31,6 +32,15 @@ import org.codelibs.fess.es.config.exentity.SuggestBadWord;
import org.codelibs.fess.es.log.exentity.SearchFieldLog;
import org.codelibs.fess.es.log.exentity.SearchLog;
import org.codelibs.fess.suggest.Suggester;
import org.codelibs.fess.suggest.concurrent.Deferred;
import org.codelibs.fess.suggest.constants.FieldNames;
import org.codelibs.fess.suggest.entity.SuggestItem;
import org.codelibs.fess.suggest.index.contents.document.DocumentReader;
import org.codelibs.fess.suggest.index.contents.document.ESSourceReader;
import org.codelibs.fess.suggest.settings.SuggestSettings;
import org.codelibs.fess.suggest.util.SuggestUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -55,16 +65,25 @@ public class SuggestHelper {
public String[] roleFieldNames = { "role" };
public String[] contentsIndex = { "content", "title" };
private static final String TEXT_SEP = " ";
protected Suggester suggester;
protected final AtomicBoolean initialized = new AtomicBoolean(false);
@PostConstruct
public void init() {
final Thread th = new Thread(() -> {
fessEsClient.admin().cluster().prepareHealth().setWaitForYellowStatus().execute().actionGet();
suggester = Suggester.builder().build(fessEsClient, fieldHelper.docIndex);
suggester.settings().array().delete(SuggestSettings.DefaultKeys.SUPPORTED_FIELDS);
for (final String field : contentsIndex) {
suggester.settings().array().add(SuggestSettings.DefaultKeys.SUPPORTED_FIELDS, field);
}
suggester.createIndexIfNothing();
initialized.set(true);
});
th.start();
}
@ -105,6 +124,49 @@ public class SuggestHelper {
suggester.refresh();
}
public void indexFromDocuments(final Consumer<Boolean> success, final Consumer<Throwable> error) {
while (!initialized.get()) {
try {
Thread.sleep(100);
} catch (Exception e) {
error.accept(e);
return;
}
}
createFessIndexTest();
DocumentReader reader = new ESSourceReader(fessEsClient, suggester.settings(), fieldHelper.docIndex, fieldHelper.docType);
suggester.indexer().indexFromDocument(reader, 2, 100).done(response -> {
suggester.refresh();
//TODO delete old doc
success.accept(true);
}).error(t -> error.accept(t));
}
public void purge(LocalDateTime time) {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.rangeQuery(FieldNames.TIMESTAMP).lt(time.format(DateTimeFormatter.BASIC_ISO_DATE)));
boolQueryBuilder.must(QueryBuilders.termQuery(FieldNames.KINDS, SuggestItem.Kind.DOCUMENT.toString()));
boolQueryBuilder.mustNot(QueryBuilders.termQuery(FieldNames.KINDS, SuggestItem.Kind.QUERY.toString()));
boolQueryBuilder.must(QueryBuilders.termQuery(FieldNames.KINDS, SuggestItem.Kind.USER.toString()));
SuggestUtil.deleteByQuery(fessEsClient, suggester.getIndex(), suggester.getType(), boolQueryBuilder);
}
public void createFessIndexTest() {
Map<String, Object> source = new HashMap<>();
source.put("content", "aaa bbbb baa aaa aaaa,,, aaa bbbb 検索 検索 「検索」");
source.put("title", "shirobako shirobako");
fessEsClient.prepareIndex(fieldHelper.docIndex, fieldHelper.docType).setSource(source).execute().actionGet();
fessEsClient.admin().indices().prepareRefresh().execute().actionGet();
}
public void refreshWords() {
deleteAllBadWord();
storeAllElevateWords();

View file

@ -0,0 +1,250 @@
package org.codelibs.fess.job;
import org.apache.commons.lang3.SystemUtils;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.fess.Constants;
import org.codelibs.fess.exception.FessSystemException;
import org.codelibs.fess.exec.SuggestCreater;
import org.codelibs.fess.helper.JobHelper;
import org.codelibs.fess.helper.SystemHelper;
import org.codelibs.fess.util.ComponentUtil;
import org.codelibs.fess.util.InputStreamThread;
import org.codelibs.fess.util.JobProcess;
import org.lastaflute.di.core.SingletonLaContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import java.io.File;
import java.io.FilenameFilter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class SuggestJob {
private static final Logger logger = LoggerFactory.getLogger(SuggestJob.class);
protected JobExecutor jobExecutor;
protected String sessionId;
protected boolean useLocaleElasticsearch = true;
protected String logFilePath;
protected int retryCountToDeleteTempDir = 10;
protected long retryIntervalToDeleteTempDir = 5000;
public SuggestJob jobExecutor(final JobExecutor jobExecutor) {
this.jobExecutor = jobExecutor;
return this;
}
public SuggestJob sessionId(final String sessionId) {
this.sessionId = sessionId;
return this;
}
public String execute(final JobExecutor jobExecutor) {
jobExecutor(jobExecutor);
return execute();
}
public String execute() {
final StringBuilder resultBuf = new StringBuilder();
if (sessionId == null) { // create session id
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
sessionId = sdf.format(new Date());
}
resultBuf.append("Session Id: ").append(sessionId).append("\n");
if (jobExecutor != null) {
jobExecutor.addShutdownListener(() -> ComponentUtil.getJobHelper().destroyCrawlerProcess(sessionId));
}
try {
executeSuggestCreater();
ComponentUtil.getKeyMatchHelper().update();
} catch (final FessSystemException e) {
throw e;
} catch (final Exception e) {
throw new FessSystemException("Failed to execute a crawl job.", e);
}
return resultBuf.toString();
}
protected void executeSuggestCreater() {
final List<String> suggestCreaterCmdList = new ArrayList<>();
final String cpSeparator = SystemUtils.IS_OS_WINDOWS ? ";" : ":";
final ServletContext servletContext = SingletonLaContainer.getComponent(ServletContext.class);
final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
final JobHelper jobHelper = ComponentUtil.getJobHelper();
suggestCreaterCmdList.add(systemHelper.getJavaCommandPath());
// -cp
suggestCreaterCmdList.add("-cp");
final StringBuilder buf = new StringBuilder();
// WEB-INF/suggest/resources
buf.append("WEB-INF");
buf.append(File.separator);
buf.append("suggest");
buf.append(File.separator);
buf.append("resources");
buf.append(cpSeparator);
// WEB-INF/classes
buf.append("WEB-INF");
buf.append(File.separator);
buf.append("classes");
// target/classes
final String userDir = System.getProperty("user.dir");
final File targetDir = new File(userDir, "target");
final File targetClassesDir = new File(targetDir, "classes");
if (targetClassesDir.isDirectory()) {
buf.append(cpSeparator);
buf.append(targetClassesDir.getAbsolutePath());
}
// WEB-INF/lib
appendJarFile(cpSeparator, buf, new File(servletContext.getRealPath("/WEB-INF/lib")), "WEB-INF/lib" + File.separator);
// WEB-INF/crawler/lib
appendJarFile(cpSeparator, buf, new File(servletContext.getRealPath("/WEB-INF/suggest/lib")), "WEB-INF/suggest" + File.separator
+ "lib" + File.separator);
final File targetLibDir = new File(targetDir, "fess" + File.separator + "WEB-INF" + File.separator + "lib");
if (targetLibDir.isDirectory()) {
appendJarFile(cpSeparator, buf, targetLibDir, targetLibDir.getAbsolutePath() + File.separator);
}
suggestCreaterCmdList.add(buf.toString());
if (useLocaleElasticsearch) {
final String transportAddresses = System.getProperty(Constants.FESS_ES_TRANSPORT_ADDRESSES);
if (StringUtil.isNotBlank(transportAddresses)) {
suggestCreaterCmdList.add("-D" + Constants.FESS_ES_TRANSPORT_ADDRESSES + "=" + transportAddresses);
}
final String clusterName = System.getProperty(Constants.FESS_ES_CLUSTER_NAME);
if (StringUtil.isNotBlank(clusterName)) {
suggestCreaterCmdList.add("-D" + Constants.FESS_ES_CLUSTER_NAME + "=" + clusterName);
}
}
suggestCreaterCmdList.add("-Dfess.suggest.process=true");
if (logFilePath == null) {
final String value = System.getProperty("fess.log.path");
logFilePath = value != null ? value : new File(targetDir, "logs").getAbsolutePath();
}
suggestCreaterCmdList.add("-Dfess.log.path=" + logFilePath);
addSystemProperty(suggestCreaterCmdList, "lasta.env", null, null);
addSystemProperty(suggestCreaterCmdList, "fess.log.name", "fess-suggest", "-suggest");
addSystemProperty(suggestCreaterCmdList, "fess.log.level", null, null);
if (systemHelper.getCrawlerJavaOptions() != null) {
for (final String value : systemHelper.getCrawlerJavaOptions()) {
suggestCreaterCmdList.add(value);
}
}
File ownTmpDir = null;
if (systemHelper.isUseOwnTmpDir()) {
final String tmpDir = System.getProperty("java.io.tmpdir");
if (StringUtil.isNotBlank(tmpDir)) {
ownTmpDir = new File(tmpDir, "fessTmpDir_" + sessionId);
if (ownTmpDir.mkdirs()) {
suggestCreaterCmdList.add("-Djava.io.tmpdir=" + ownTmpDir.getAbsolutePath());
} else {
ownTmpDir = null;
}
}
}
suggestCreaterCmdList.add(SuggestCreater.class.getCanonicalName());
suggestCreaterCmdList.add("--sessionId");
suggestCreaterCmdList.add(sessionId);
final File baseDir = new File(servletContext.getRealPath("/WEB-INF")).getParentFile();
if (logger.isInfoEnabled()) {
logger.info("SuggestCreater: \nDirectory=" + baseDir + "\nOptions=" + suggestCreaterCmdList);
}
final ProcessBuilder pb = new ProcessBuilder(suggestCreaterCmdList);
pb.directory(baseDir);
pb.redirectErrorStream(true);
try {
final JobProcess jobProcess = jobHelper.startCrawlerProcess(sessionId, pb);
final InputStreamThread it = jobProcess.getInputStreamThread();
it.start();
final Process currentProcess = jobProcess.getProcess();
currentProcess.waitFor();
it.join(5000);
final int exitValue = currentProcess.exitValue();
if (logger.isInfoEnabled()) {
logger.info("SuggestCreater: Exit Code=" + exitValue + " - SuggestCreater Process Output:\n" + it.getOutput());
}
if (exitValue != 0) {
throw new FessSystemException("Exit Code: " + exitValue + "\nOutput:\n" + it.getOutput());
}
} catch (final FessSystemException e) {
throw e;
} catch (final InterruptedException e) {
logger.warn("SuggestCreater Process interrupted.");
} catch (final Exception e) {
throw new FessSystemException("SuggestCreater Process terminated.", e);
} finally {
try {
jobHelper.destroyCrawlerProcess(sessionId);
} finally {
deleteTempDir(ownTmpDir);
}
}
}
private void addSystemProperty(final List<String> crawlerCmdList, final String name, final String defaultValue, final String appendValue) {
final String value = System.getProperty(name);
if (value != null) {
final StringBuilder buf = new StringBuilder();
buf.append("-D").append(name).append("=").append(value);
if (appendValue != null) {
buf.append(appendValue);
}
crawlerCmdList.add(buf.toString());
} else if (defaultValue != null) {
crawlerCmdList.add("-D" + name + "=" + defaultValue);
}
}
protected void deleteTempDir(final File ownTmpDir) {
if (ownTmpDir == null) {
return;
}
for (int i = 0; i < retryCountToDeleteTempDir; i++) {
if (ownTmpDir.delete()) {
return;
}
try {
Thread.sleep(retryIntervalToDeleteTempDir);
} catch (final InterruptedException e) {
// ignore
}
}
logger.warn("Could not delete a temp dir: " + ownTmpDir.getAbsolutePath());
}
protected void appendJarFile(final String cpSeparator, final StringBuilder buf, final File libDir, final String basePath) {
final File[] jarFiles = libDir.listFiles((FilenameFilter) (dir, name) -> name.toLowerCase().endsWith(".jar"));
if (jarFiles != null) {
for (final File file : jarFiles) {
buf.append(cpSeparator);
buf.append(basePath);
buf.append(file.getName());
}
}
}
}

View file

@ -139,8 +139,6 @@
<property name="roleSeparator">","</property>
-->
</component>
<!-- TODO
<component name="suggestHelper" class="org.codelibs.fess.helper.SuggestHelper">
</component>
-->
</components>

View file

@ -1,8 +1,10 @@
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"1"}}
{"name":"Crawler","target":"all","cronExpression":"0 0 0 * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"crawlJob\").execute(executor);","jobLogging":true,"crawler":true,"available":true,"sortOrder":0,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"2"}}
{"name":"Minutely Tasks","target":"all","cronExpression":"0 * * * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"aggregateLogJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":0,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"name":"Suggest","target":"all","cronExpression":"0 0 0 * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"suggestJob\").execute(executor);","jobLogging":true,"crawler":false,"available":true,"sortOrder":0,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"3"}}
{"name":"Hourly Tasks","target":"all","cronExpression":"0 0 * * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"updateHotWordJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":0,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"name":"Minutely Tasks","target":"all","cronExpression":"0 * * * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"aggregateLogJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":0,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"4"}}
{"name":"Hourly Tasks","target":"all","cronExpression":"0 0 * * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"updateHotWordJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":0,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"5"}}
{"name":"Daily Tasks","target":"all","cronExpression":"0 0 0 * * ?","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeLogJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":0,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}

View file

@ -10,6 +10,8 @@
<!-- Jobs -->
<component name="crawlJob" class="org.codelibs.fess.job.CrawlJob" instance="prototype">
</component>
<component name="suggestJob" class="org.codelibs.fess.job.SuggestJob" instance="prototype">
</component>
<component name="aggregateLogJob" class="org.codelibs.fess.job.AggregateLogJob" instance="prototype">
</component>
<component name="updateHotWordJob" class="org.codelibs.fess.job.UpdateHotWordJob" instance="prototype">

View file

@ -5,86 +5,8 @@
<include path="convention.xml" />
<include path="fess.xml" />
<include path="crawler_es.xml" />
<component name="indexingHelper" class="org.codelibs.fess.helper.IndexingHelper">
</component>
<component name="labelTypeHelper" class="org.codelibs.fess.helper.LabelTypeHelper">
</component>
<component name="webFsIndexHelper" class="org.codelibs.fess.helper.WebFsIndexHelper">
</component>
<component name="dataIndexHelper" class="org.codelibs.fess.helper.DataIndexHelper">
</component>
<component name="overlappingHostHelper" class="org.codelibs.fess.helper.OverlappingHostHelper">
</component>
<component name="intervalControlHelper" class="org.codelibs.fess.helper.IntervalControlHelper">
<!--
<postConstruct name="addIntervalRule">
<arg>"5:00"</arg>
<arg>"10:00"</arg>
<arg>"2,3,4,5,6"</arg>
<arg>3600000</arg>
</postConstruct>
-->
</component>
<component name="sambaHelper" class="org.codelibs.fess.helper.SambaHelper">
</component>
<component name="indexUpdater" class="org.codelibs.fess.indexer.IndexUpdater"
instance="prototype">
<!--
<property name="maxDocumentCacheSize">5</property>
<property name="unprocessedDocumentSize">100</property>
<property name="threadDump">false</property>
<postConstruct name="addBoostDocumentRule">
<arg>
<component class="org.codelibs.fess.indexer.BoostDocumentRule">
<property name="matchExpression">"url.matches(\".*fess.*\")"</property>
<property name="boostExpression">"1000.0"</property>
</component>
</arg>
</postConstruct>
<postConstruct name="addDefaultDocValue">
<arg>"FieldName"</arg>
<arg>"VALUE"</arg>
</postConstruct>
-->
</component>
<component name="fileTypeHelper" class="org.codelibs.fess.helper.FileTypeHelper">
<postConstruct name="add">
<arg>"text/html"</arg>
<arg>"html"</arg>
</postConstruct>
<postConstruct name="add">
<arg>"application/msword"</arg>
<arg>"word"</arg>
</postConstruct>
<postConstruct name="add">
<arg>"application/vnd.openxmlformats-officedocument.wordprocessingml.document"</arg>
<arg>"word"</arg>
</postConstruct>
<postConstruct name="add">
<arg>"application/vnd.ms-excel"</arg>
<arg>"excel"</arg>
</postConstruct>
<postConstruct name="add">
<arg>"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"</arg>
<arg>"excel"</arg>
</postConstruct>
<postConstruct name="add">
<arg>"application/vnd.ms-powerpoint"</arg>
<arg>"powerpoint"</arg>
</postConstruct>
<postConstruct name="add">
<arg>"application/vnd.openxmlformats-officedocument.presentationml.presentation"</arg>
<arg>"powerpoint"</arg>
</postConstruct>
<postConstruct name="add">
<arg>"application/pdf"</arg>
<arg>"pdf"</arg>
</postConstruct>
</component>
<component name="fessCrawler" class="org.codelibs.fess.exec.Crawler"
instance="prototype">
<component name="fessSuggest" class="org.codelibs.fess.exec.SuggestCreater"
instance="prototype">
</component>
</components>

View file

@ -21,7 +21,7 @@ $(function(){
$('#contentQuery').suggestor( {
ajaxinfo: {
url: contextPath + '/suggest',
fn: '_default',
fn: '_default,content,title',
num: 10
},
boxCssInfo: {

View file

@ -66,7 +66,7 @@ $(function(){
}
$screenshot.children().remove();
var content = '<a href="' + buf.join('') + '"><img src="screenshot?queryId='
+ queryId + '&docId=' + docId + '"></a>'
$screenshot.append(content);
@ -100,7 +100,7 @@ $(function(){
queryId: $queryId.val()
}
}).done(function ( data ) {
if(data.response.status === 0
if(data.response.status === 0
&& typeof data.response.result !== 'undefined'
&& data.response.result === 'ok'){
var $favorited = $favorite.siblings('.favorited');
@ -129,7 +129,7 @@ $(function(){
queryId: $queryId.val()
}
}).done(function ( data ) {
if(data.response.status === 0
if(data.response.status === 0
&& typeof data.response.num !== 'undefined'
&& data.response.num > 0){
var docIds = data.response.docIds;
@ -174,7 +174,7 @@ $(function(){
$('#query').suggestor( {
ajaxinfo: {
url: contextPath + '/suggest',
fn: '_default',
fn: '_default,content,title',
num: 10
},
boxCssInfo: {