deniskuzZ commented on code in PR #6595:
URL: https://github.com/apache/hive/pull/6595#discussion_r4284488177


##########
standalone-metastore/metastore-search/src/main/java/org/apache/hive/search/mapping/IndexMapping.java:
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.hive.search.mapping;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hive.search.config.IndexOptions;
+import org.apache.hive.search.config.IndexStoreOptions;
+import org.apache.hive.search.config.InferenceOptions;
+import org.apache.hive.search.config.SearchOptions;
+import org.apache.hive.search.exception.SearchException;
+import org.apache.hive.search.metastore.MetastoreTableMapper;
+import org.apache.hive.search.metastore.SearchTextSegment;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.core.KeywordAnalyzer;
+import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+
+public record IndexMapping(Configuration configuration, Map<String, 
FieldSchema> fields) {

Review Comment:
   The mapping package (FieldSchema, TextFieldSchema, BinaryFieldSchema, 
IndexMapping, Field/TextField/IdField/BinaryField, TableDocument) is 
essentially a hand-rolled object→document mapper, but we only have a single 
document type with ~10 fixed fields. Lucene’s own field classes already are the 
mapping layer, so this adds indirection without buying flexibility.
   
   Two alternatives worth considering:
   
   Option A: Hibernate Search (standalone POJO mapper). This is what the design 
doc already points to for Phase 3. hibernate-search-mapper-pojo-standalone 
doesn’t require Hibernate ORM, so it works with our Thrift Table (or a thin 
TableIndexView record). It is Apache-2.0 licensed as of 8.x, so it is fine for 
an ASF project. It would give us:
   
   - declarative mapping (@FullTextField, @KeywordField, @VectorField, 
@DocumentId) in place of the schema/field class hierarchy;
   - analyzer configuration, mass indexing (MassIndexer), which could replace 
BootstrapIndexer’s fetch/queue/writer plumbing, and atomic document updates out 
of the box;
   - the embedded-Lucene ↔ Elasticsearch/OpenSearch backend switch that §2.8 / 
Phase 3 describes, without us maintaining SearchBackend ourselves.
   
   Things to check before committing to it: which Lucene version its Lucene 
backend pins (we’re on 10.5 and use BayesianScoreQuery / LogOddsFusionQuery; 
the hybrid fusion would likely need the native Lucene query extension); and the 
extra dependency footprint in the HMS classpath.
   
   Option B: collapse the framework. If we’d rather avoid the dependency, a 
single TableDocumentBuilder that turns a Table (plus embeddings) into a Lucene 
Document directly, plus a TableIndexFields constants class, would replace most 
of the package:
   
   ````
   final class TableDocumentBuilder {
     static Document build(Table t, List<float[]> segmentVectors) {
       Document d = new Document();
       String id = TableIndexFields.id(t);
       d.add(new StringField(ID, id, Store.YES));
       d.add(new StringField(DB_FILTER, t.getDbName(), Store.NO));
       d.add(new TextField(TABLE, t.getTableName().toLowerCase(Locale.ROOT), 
Store.NO));
       d.add(new TextField(COLUMNS, columnNames(t), Store.YES));
       d.add(new TextField(COMMENT, comment(t), Store.YES));
       ...
       return d;
     }
   }
   ````
   Analyzers then stay in one PerFieldAnalyzerWrapper, and the “which fields 
are lexical/semantic/filter” knowledge lives in one place instead of being 
split between MetastoreIndexSchema, TextFieldSchema flags, 
TableDocument.toDocumentField and IndexMapping.resolve*.
   
   Related: for the multi-segment embeddings, consider a parent/child block 
(one child doc per segment, a single vector field, queried with 
DiversifyingChildrenFloatKnnVectorQuery) instead of search_text_0..N fields. 
That avoids N separate HNSW graphs per index, and writer.updateDocuments(term, 
block) gives an atomic replace, which also fixes the delete-then-add gap in 
Indexer.addDocuments.
   
   Small things in the current code: TableDocument.toDocuments() mutates a 
member Document, so a second call duplicates fields; it returns List<Document>, 
but blocks are never used; and IndexMapping.resolveSemanticSearchFields has a 
dead statement (SearchTextSegment.isSegmentField(fieldName);, result discarded).
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to