View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.query;
17  
18  import org.apache.logging.log4j.LogManager;
19  import org.apache.logging.log4j.Logger;
20  import org.apache.lucene.search.BooleanClause;
21  import org.apache.lucene.search.BooleanQuery;
22  import org.apache.lucene.search.Query;
23  import org.codelibs.fess.entity.QueryContext;
24  import org.codelibs.fess.exception.InvalidQueryException;
25  import org.lastaflute.core.message.UserMessages;
26  import org.opensearch.index.query.BoolQueryBuilder;
27  import org.opensearch.index.query.QueryBuilder;
28  import org.opensearch.index.query.QueryBuilders;
29  
30  /**
31   * Query command implementation for handling Boolean queries.
32   * Converts Lucene BooleanQuery objects to OpenSearch BoolQueryBuilder objects.
33   */
34  public class BooleanQueryCommand extends QueryCommand {
35      /**
36       * Default constructor for BooleanQueryCommand.
37       */
38      public BooleanQueryCommand() {
39          super();
40      }
41  
42      private static final Logger logger = LogManager.getLogger(BooleanQueryCommand.class);
43  
44      @Override
45      protected String getQueryClassName() {
46          return BooleanQuery.class.getSimpleName();
47      }
48  
49      @Override
50      public QueryBuilder execute(final QueryContext context, final Query query, final float boost) {
51          if (query instanceof final BooleanQuery booleanQuery) {
52              if (logger.isDebugEnabled()) {
53                  logger.debug("BooleanQuery: query={}, boost={}", query, boost);
54              }
55              return convertBooleanQuery(context, booleanQuery, boost);
56          }
57          throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryUnknown(UserMessages.GLOBAL_PROPERTY_KEY),
58                  "Unknown q: " + query.getClass() + " => " + query);
59      }
60  
61      /**
62       * Converts a Lucene BooleanQuery to an OpenSearch BoolQueryBuilder.
63       * @param context The query context.
64       * @param booleanQuery The boolean query to convert.
65       * @param boost The boost factor to apply.
66       * @return The converted BoolQueryBuilder.
67       */
68      protected QueryBuilder convertBooleanQuery(final QueryContext context, final BooleanQuery booleanQuery, final float boost) {
69          final BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
70          for (final BooleanClause clause : booleanQuery.clauses()) {
71              final QueryBuilder queryBuilder = getQueryProcessor().execute(context, clause.query(), boost);
72              if (queryBuilder != null) {
73                  switch (clause.occur()) {
74                  case MUST:
75                      boolQuery.must(queryBuilder);
76                      break;
77                  case SHOULD:
78                      boolQuery.should(queryBuilder);
79                      break;
80                  case MUST_NOT:
81                      boolQuery.mustNot(queryBuilder);
82                      break;
83                  default:
84                      break;
85                  }
86              }
87          }
88          if (boolQuery.hasClauses()) {
89              return boolQuery;
90          }
91          return null;
92      }
93  }