|
|
@@ -10,6 +10,7 @@ import java.util.Map;
|
|
|
import java.util.Map.Entry;
|
|
|
import java.util.Set;
|
|
|
|
|
|
+import org.apache.commons.lang3.ArrayUtils;
|
|
|
import org.apache.lucene.document.Document;
|
|
|
import org.apache.lucene.search.BooleanClause;
|
|
|
import org.apache.lucene.search.BooleanClause.Occur;
|
|
|
@@ -63,7 +64,9 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
|
|
|
// 获取单据的id
|
|
|
List<Long> content = new ArrayList<>();
|
|
|
try {
|
|
|
- SPage<ScoreDoc> scoreDocPage = search(indexSearcher, keyword, tableName, pageParams);
|
|
|
+ // 获取该表keyword可以搜索的域
|
|
|
+ List<String> keywordFields = ClassAndTableNameUtils.getKeywordFields(tableName);
|
|
|
+ SPage<ScoreDoc> scoreDocPage = search(indexSearcher, keyword, tableName, keywordFields, true, pageParams);
|
|
|
SPage<Long> sPage = convertSPage(scoreDocPage, Long.class);
|
|
|
for (ScoreDoc scoreDoc : scoreDocPage.getContent()) {
|
|
|
Document document = indexSearcher.doc(scoreDoc.doc);
|
|
|
@@ -78,6 +81,53 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public SPage<String> similar(String keyword, Table_name tableName, Integer size, String... fields)
|
|
|
+ throws SearchException, IllegalArgumentException {
|
|
|
+ if (ArrayUtils.isEmpty(fields)) {
|
|
|
+ throw new IllegalArgumentException("fields不可为空");
|
|
|
+ }
|
|
|
+ if (keyword == null) {
|
|
|
+ keyword = "";
|
|
|
+ }
|
|
|
+
|
|
|
+ PageParams pageParams = new PageParams();
|
|
|
+ if (size == null || size < 1) {
|
|
|
+ size = PAGE_SIZE;
|
|
|
+ }
|
|
|
+ pageParams.setPage(PAGE_INDEX);
|
|
|
+ pageParams.setSize(size);
|
|
|
+
|
|
|
+ IndexSearcher indexSearcher = SearchUtils.getIndexSearcher(tableName);
|
|
|
+ List<String> content = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ List<String> keywordFields = new ArrayList<>();
|
|
|
+ for (String field : fields) {
|
|
|
+ keywordFields.add(ClassAndTableNameUtils.combineField(tableName, field));
|
|
|
+ }
|
|
|
+ // 获取联想词时,不进行分词
|
|
|
+ SPage<ScoreDoc> scoreDocPage = search(indexSearcher, keyword, tableName, keywordFields, false, pageParams);
|
|
|
+ SPage<String> sPage = convertSPage(scoreDocPage, String.class);
|
|
|
+ for (ScoreDoc scoreDoc : scoreDocPage.getContent()) {
|
|
|
+ Document document = indexSearcher.doc(scoreDoc.doc);
|
|
|
+ for (String field : keywordFields) {
|
|
|
+ String value = document.get(field);
|
|
|
+ // 需包含关键词,才作为联想词(关键词视为一个完整的字符串,中间不能掺有其他字符)
|
|
|
+ if (value != null && value.toUpperCase().contains(keyword.toUpperCase())) {
|
|
|
+ content.add(value);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sPage.setContent(content);
|
|
|
+ return sPage;
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new SearchException(e).setDetailedMessage(e);
|
|
|
+ } finally {
|
|
|
+ SearchUtils.releaseIndexSearcher(indexSearcher);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 转换SPage
|
|
|
*
|
|
|
@@ -100,6 +150,10 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
|
|
|
* 物料编号、 物料名称、物料规格
|
|
|
* @param tableName
|
|
|
* 不为空,单据类型
|
|
|
+ * @param keywordFields
|
|
|
+ * 不为空,模糊搜索的域,多个域之间取或操作
|
|
|
+ * @param tokenized
|
|
|
+ * 可为空,模糊搜索时,是否对关键词进行分词,为空时,不分词
|
|
|
* @param pageParams
|
|
|
* 可为空,可能含有翻页信息,filters中可能有过滤信息,包括:1.状态、所属企业uu、其他状态(如已采纳、未采纳等),
|
|
|
* 该部分参数的键为数据库表中相应的字段名称,值为字段对应的值,若值有多个,则使用com.uas.search.b2b.
|
|
|
@@ -113,10 +167,11 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
|
|
|
*/
|
|
|
@SuppressWarnings("unchecked")
|
|
|
private SPage<ScoreDoc> search(IndexSearcher indexSearcher, String keyword, Table_name tableName,
|
|
|
- PageParams pageParams) throws IOException {
|
|
|
+ List<String> keywordFields, Boolean tokenized, PageParams pageParams) throws IOException {
|
|
|
|
|
|
- // 获取该表keyword可以搜索的域
|
|
|
- List<String> keywordFields = ClassAndTableNameUtils.getKeywordFields(tableName);
|
|
|
+ if (CollectionUtils.isEmpty(keywordFields)) {
|
|
|
+ throw new IllegalArgumentException("keywordFields不可为空");
|
|
|
+ }
|
|
|
|
|
|
SPage<ScoreDoc> sPage = new SPage<>();
|
|
|
BooleanQuery booleanQuery = new BooleanQuery();
|
|
|
@@ -132,7 +187,7 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
|
|
|
// keyword可能是哪些域,域之间进行或操作
|
|
|
BooleanQuery booleanQuery2 = new BooleanQuery();
|
|
|
for (String keywordField : keywordFields) {
|
|
|
- booleanQuery2.add(SearchUtils.getBooleanQuery(keywordField, str), BooleanClause.Occur.SHOULD);
|
|
|
+ booleanQuery2.add(SearchUtils.regexpQuery(keywordField, str, tokenized), BooleanClause.Occur.SHOULD);
|
|
|
}
|
|
|
booleanQuery.add(booleanQuery2, BooleanClause.Occur.MUST);
|
|
|
}
|
|
|
@@ -221,12 +276,12 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
|
|
|
Occur occur = multiValue.isOr() ? Occur.SHOULD : Occur.MUST;
|
|
|
BooleanQuery booleanQuery2 = new BooleanQuery();
|
|
|
for (Object object : values) {
|
|
|
- booleanQuery2.add(SearchUtils.getRegexpQuery(field, String.valueOf(object)), occur);
|
|
|
+ booleanQuery2.add(SearchUtils.regexpQuery(field, String.valueOf(object), false), occur);
|
|
|
}
|
|
|
booleanQuery.add(booleanQuery2, Occur.MUST);
|
|
|
} else {
|
|
|
if (value != null) {
|
|
|
- booleanQuery.add(SearchUtils.getRegexpQuery(field, String.valueOf(value)), Occur.MUST);
|
|
|
+ booleanQuery.add(SearchUtils.regexpQuery(field, String.valueOf(value), false), Occur.MUST);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -304,7 +359,9 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
|
|
|
PageParams pageParams = new PageParams();
|
|
|
pageParams.setPage(page);
|
|
|
pageParams.setSize(size);
|
|
|
- SPage<ScoreDoc> scoreDocPage = search(indexSearcher, null, tableName, pageParams);
|
|
|
+ // 获取该表keyword可以搜索的域
|
|
|
+ List<String> keywordFields = ClassAndTableNameUtils.getKeywordFields(tableName);
|
|
|
+ SPage<ScoreDoc> scoreDocPage = search(indexSearcher, null, tableName, keywordFields, null, pageParams);
|
|
|
SPage<T> sPage = convertSPage(scoreDocPage, clazz);
|
|
|
for (ScoreDoc scoreDoc : scoreDocPage.getContent()) {
|
|
|
Document document = indexSearcher.doc(scoreDoc.doc);
|