|
32 | 32 | public abstract class RowRecordWrapper {
|
33 | 33 | // a cache for output fields
|
34 | 34 | private ConcurrentHashMap<String, FieldDataWrapper> outputFieldsData = new ConcurrentHashMap<>();
|
| 35 | + // a cache for output dynamic field names |
| 36 | + private List<String> dynamicFieldNames = null; |
35 | 37 |
|
36 | 38 | public abstract List<QueryResultsWrapper.RowRecord> getRowRecords();
|
37 | 39 |
|
@@ -69,46 +71,75 @@ public FieldDataWrapper getDynamicWrapper() throws ParamException {
|
69 | 71 | * @return <code>RowRecord</code> a row record of the result
|
70 | 72 | */
|
71 | 73 | protected QueryResultsWrapper.RowRecord buildRowRecord(QueryResultsWrapper.RowRecord record, long index) {
|
72 |
| - for (String outputKey : getOutputFields()) { |
73 |
| - boolean isField = false; |
74 |
| - for (FieldData field : getFieldDataList()) { |
75 |
| - if (outputKey.equals(field.getFieldName())) { |
76 |
| - FieldDataWrapper wrapper = getFieldWrapperInternal(field); |
77 |
| - if (index < 0 || index >= wrapper.getRowCount()) { |
78 |
| - throw new ParamException("Index out of range"); |
79 |
| - } |
80 |
| - Object value = wrapper.valueByIdx((int)index); |
81 |
| - if (wrapper.isJsonField()) { |
82 |
| - JsonElement jsonField = FieldDataWrapper.ParseJSONObject(value); |
83 |
| - if (wrapper.isDynamicField() && jsonField instanceof JsonObject) { |
84 |
| - JsonObject jsonObj = (JsonObject) jsonField; |
85 |
| - for (String key: jsonObj.keySet()) { |
86 |
| - record.put(key, FieldDataWrapper.ValueOfJSONElement(jsonObj.get(key))); |
87 |
| - } |
88 |
| - } else { |
89 |
| - record.put(field.getFieldName(), jsonField); |
90 |
| - } |
91 |
| - } else { |
92 |
| - record.put(field.getFieldName(), value); |
93 |
| - } |
94 |
| - isField = true; |
95 |
| - break; |
96 |
| - } |
| 74 | + List<String> dynamicFields = getDynamicFieldNames(); |
| 75 | + List<FieldData> fieldsData = getFieldDataList(); |
| 76 | + for (FieldData field : fieldsData) { |
| 77 | + FieldDataWrapper wrapper = getFieldWrapperInternal(field); |
| 78 | + if (index < 0 || index >= wrapper.getRowCount()) { |
| 79 | + throw new ParamException("Index out of range"); |
97 | 80 | }
|
| 81 | + Object value = wrapper.valueByIdx((int)index); |
| 82 | + if (wrapper.isJsonField()) { |
| 83 | + JsonElement jsonValue = FieldDataWrapper.ParseJSONObject(value); |
| 84 | + if (!field.getIsDynamic()) { |
| 85 | + record.put(field.getFieldName(), jsonValue); |
| 86 | + continue; |
| 87 | + } |
98 | 88 |
|
99 |
| - // if the output field is not a field name, fetch it from dynamic field |
100 |
| - if (!isField) { |
101 |
| - FieldDataWrapper dynamicField = getDynamicWrapper(); |
102 |
| - Object obj = dynamicField.get((int)index, outputKey); |
103 |
| - if (obj != null) { |
104 |
| - record.put(outputKey, obj); |
| 89 | + // dynamic field, the value must be a dict |
| 90 | + if (!(jsonValue instanceof JsonObject)) { |
| 91 | + throw new ParamException("The content of dynamic field is not a JSON dict"); |
105 | 92 | }
|
| 93 | + |
| 94 | + JsonObject jsonDict = (JsonObject)jsonValue; |
| 95 | + // the outputFields of QueryRequest/SearchRequest contains a "$meta" |
| 96 | + // put all key/value pairs of "$meta" into record |
| 97 | + // else pick some key/value pairs according to the dynamicFields |
| 98 | + for (String key: jsonDict.keySet()) { |
| 99 | + if (dynamicFields.isEmpty() || dynamicFields.contains(key)) { |
| 100 | + record.put(key, FieldDataWrapper.ValueOfJSONElement(jsonDict.get(key))); |
| 101 | + } |
| 102 | + } |
| 103 | + } else { |
| 104 | + record.put(field.getFieldName(), value); |
106 | 105 | }
|
107 | 106 | }
|
| 107 | + |
108 | 108 | return record;
|
109 | 109 | }
|
110 | 110 |
|
| 111 | + private List<String> getDynamicFieldNames() { |
| 112 | + if (dynamicFieldNames != null) { |
| 113 | + return dynamicFieldNames; |
| 114 | + } |
| 115 | + |
| 116 | + dynamicFieldNames = new ArrayList<>(); |
| 117 | + // find out dynamic field names |
| 118 | + List<FieldData> fieldsData = getFieldDataList(); |
| 119 | + String dynamicFieldName = null; |
| 120 | + List<String> fieldNames = new ArrayList<>(); |
| 121 | + for (FieldData field : fieldsData) { |
| 122 | + if (!fieldNames.contains(field.getFieldName())) { |
| 123 | + fieldNames.add(field.getFieldName()); |
| 124 | + } |
| 125 | + if (field.getIsDynamic()) { |
| 126 | + dynamicFieldName = field.getFieldName(); |
| 127 | + } |
| 128 | + } |
| 129 | + |
| 130 | + List<String> outputNames = getOutputFields(); |
| 131 | + for (String name : outputNames) { |
| 132 | + if (name.equals(dynamicFieldName)) { |
| 133 | + dynamicFieldNames.clear(); |
| 134 | + break; |
| 135 | + } |
| 136 | + if (!fieldNames.contains(name)) { |
| 137 | + dynamicFieldNames.add(name); |
| 138 | + } |
| 139 | + } |
| 140 | + return dynamicFieldNames; |
| 141 | + } |
| 142 | + |
111 | 143 | protected abstract List<FieldData> getFieldDataList();
|
112 | 144 | protected abstract List<String> getOutputFields();
|
113 |
| - |
114 | 145 | }
|
0 commit comments