15
15
*/
16
16
package org .springframework .data .elasticsearch .core ;
17
17
18
- import com .fasterxml .jackson .databind .ObjectReader ;
19
- import com .fasterxml .jackson .databind .ObjectWriter ;
20
18
import lombok .RequiredArgsConstructor ;
21
19
22
20
import java .io .IOException ;
34
32
import org .springframework .data .convert .EntityInstantiators ;
35
33
import org .springframework .data .convert .EntityReader ;
36
34
import org .springframework .data .convert .EntityWriter ;
35
+ import org .springframework .data .elasticsearch .Document ;
36
+ import org .springframework .data .elasticsearch .SearchDocument ;
37
37
import org .springframework .data .elasticsearch .core .convert .ElasticsearchCustomConversions ;
38
38
import org .springframework .data .elasticsearch .core .convert .ElasticsearchTypeMapper ;
39
39
import org .springframework .data .elasticsearch .core .mapping .ElasticsearchPersistentEntity ;
52
52
import org .springframework .util .ObjectUtils ;
53
53
54
54
import com .fasterxml .jackson .databind .ObjectMapper ;
55
+ import com .fasterxml .jackson .databind .ObjectReader ;
56
+ import com .fasterxml .jackson .databind .ObjectWriter ;
55
57
56
58
/**
57
59
* Elasticsearch specific {@link EntityReader} & {@link EntityWriter} implementation based on domain type
58
60
* {@link ElasticsearchPersistentEntity metadata}.
59
61
*
60
62
* @author Christoph Strobl
61
63
* @author Peter-Josef Meisch
64
+ * @author Mark Paluch
62
65
* @since 3.2
63
66
*/
64
- public class ElasticsearchEntityMapper implements
65
- EntityConverter <ElasticsearchPersistentEntity <?>, ElasticsearchPersistentProperty , Object , Map <String , Object >>,
66
- EntityWriter <Object , Map <String , Object >>, EntityReader <Object , Map <String , Object >>, InitializingBean ,
67
- EntityMapper {
67
+ public class ElasticsearchEntityMapper
68
+ implements EntityConverter <ElasticsearchPersistentEntity <?>, ElasticsearchPersistentProperty , Object , Document >,
69
+ EntityWriter <Object , Document >, EntityReader <Object , Document >, InitializingBean , EntityMapper {
68
70
69
71
private final MappingContext <? extends ElasticsearchPersistentEntity <?>, ElasticsearchPersistentProperty > mappingContext ;
70
72
private final GenericConversionService conversionService ;
@@ -134,14 +136,14 @@ public void afterPropertiesSet() {
134
136
// --> READ
135
137
136
138
@ Override
137
- public <T > T readObject (Map < String , Object > source , Class <T > targetType ) {
139
+ public <T > T readObject (Document source , Class <T > targetType ) {
138
140
return read (targetType , source );
139
141
}
140
142
141
143
@ SuppressWarnings ("unchecked" )
142
144
@ Override
143
145
@ Nullable
144
- public <R > R read (Class <R > type , Map < String , Object > source ) {
146
+ public <R > R read (Class <R > type , Document source ) {
145
147
return doRead (source , ClassTypeInformation .from ((Class <R >) ClassUtils .getUserClass (type )));
146
148
}
147
149
@@ -320,16 +322,16 @@ private Object readSimpleValue(@Nullable Object value, TypeInformation<?> target
320
322
// --> WRITE
321
323
322
324
@ Override
323
- public Map < String , Object > mapObject (Object source ) {
325
+ public Document mapObject (Object source ) {
324
326
325
- LinkedHashMap < String , Object > target = new LinkedHashMap <> ();
327
+ Document target = Document . create ();
326
328
write (source , target );
327
329
return target ;
328
330
}
329
331
330
332
@ SuppressWarnings ("unchecked" )
331
333
@ Override
332
- public void write (@ Nullable Object source , Map < String , Object > sink ) {
334
+ public void write (@ Nullable Object source , Document sink ) {
333
335
334
336
if (source == null ) {
335
337
return ;
@@ -351,8 +353,7 @@ public void write(@Nullable Object source, Map<String, Object> sink) {
351
353
doWrite (source , sink , type );
352
354
}
353
355
354
- protected void doWrite (@ Nullable Object source , Map <String , Object > sink ,
355
- @ Nullable TypeInformation <? extends Object > typeHint ) {
356
+ protected void doWrite (@ Nullable Object source , Document sink , @ Nullable TypeInformation <? extends Object > typeHint ) {
356
357
357
358
if (source == null ) {
358
359
return ;
@@ -382,7 +383,7 @@ protected void doWrite(@Nullable Object source, Map<String, Object> sink,
382
383
writeEntity (entity , source , sink , null );
383
384
}
384
385
385
- protected void writeEntity (ElasticsearchPersistentEntity <?> entity , Object source , Map < String , Object > sink ,
386
+ protected void writeEntity (ElasticsearchPersistentEntity <?> entity , Object source , Document sink ,
386
387
@ Nullable TypeInformation containingStructure ) {
387
388
388
389
PersistentPropertyAccessor <?> accessor = entity .getPropertyAccessor (source );
@@ -391,11 +392,11 @@ protected void writeEntity(ElasticsearchPersistentEntity<?> entity, Object sourc
391
392
typeMapper .writeType (source .getClass (), sink );
392
393
}
393
394
394
- writeProperties (entity , accessor , sink );
395
+ writeProperties (entity , accessor , new MapValueAccessor ( sink ) );
395
396
}
396
397
397
398
protected void writeProperties (ElasticsearchPersistentEntity <?> entity , PersistentPropertyAccessor <?> accessor ,
398
- Map < String , Object > sink ) {
399
+ MapValueAccessor sink ) {
399
400
400
401
for (ElasticsearchPersistentProperty property : entity ) {
401
402
@@ -412,19 +413,19 @@ protected void writeProperties(ElasticsearchPersistentEntity<?> entity, Persiste
412
413
if (!isSimpleType (value )) {
413
414
writeProperty (property , value , sink );
414
415
} else {
415
- sink .put (property . getFieldName () , getWriteSimpleValue (value ));
416
+ sink .set (property , getWriteSimpleValue (value ));
416
417
}
417
418
}
418
419
}
419
420
420
- protected void writeProperty (ElasticsearchPersistentProperty property , Object value , Map < String , Object > sink ) {
421
+ protected void writeProperty (ElasticsearchPersistentProperty property , Object value , MapValueAccessor sink ) {
421
422
422
423
Optional <Class <?>> customWriteTarget = conversions .getCustomWriteTarget (value .getClass ());
423
424
424
425
if (customWriteTarget .isPresent ()) {
425
426
426
427
Class <?> writeTarget = customWriteTarget .get ();
427
- sink .put (property . getFieldName () , conversionService .convert (value , writeTarget ));
428
+ sink .set (property , conversionService .convert (value , writeTarget ));
428
429
return ;
429
430
}
430
431
@@ -442,7 +443,7 @@ protected void writeProperty(ElasticsearchPersistentProperty property, Object va
442
443
}
443
444
}
444
445
445
- sink .put (property . getFieldName () , getWriteComplexValue (property , typeHint , value ));
446
+ sink .set (property , getWriteComplexValue (property , typeHint , value ));
446
447
}
447
448
448
449
protected Object getWriteSimpleValue (Object value ) {
@@ -479,7 +480,8 @@ protected Object getWriteComplexValue(ElasticsearchPersistentProperty property,
479
480
}
480
481
481
482
private Object writeEntity (Object value , ElasticsearchPersistentProperty property , TypeInformation <?> typeHint ) {
482
- Map <String , Object > target = new LinkedHashMap <>();
483
+
484
+ Document target = Document .create ();
483
485
writeEntity (mappingContext .getRequiredPersistentEntity (value .getClass ()), value , target ,
484
486
property .getTypeInformation ());
485
487
return target ;
@@ -549,15 +551,15 @@ private Object writeCollectionValue(Object value, ElasticsearchPersistentPropert
549
551
@ Override
550
552
public String mapToString (Object source ) throws IOException {
551
553
552
- Map < String , Object > sink = new LinkedHashMap <> ();
554
+ Document sink = Document . create ();
553
555
write (source , sink );
554
556
555
- return objectWriter .writeValueAsString (sink );
557
+ return objectWriter .writeValueAsString (new LinkedHashMap <>( sink ) );
556
558
}
557
559
558
560
@ Override
559
561
public <T > T mapToObject (String source , Class <T > clazz ) throws IOException {
560
- return read (clazz , objectReader .readValue (source ));
562
+ return read (clazz , Document . from ( objectReader .readValue (source ) ));
561
563
}
562
564
563
565
// --> PRIVATE HELPERS
@@ -669,6 +671,18 @@ static class MapValueAccessor {
669
671
670
672
public Object get (ElasticsearchPersistentProperty property ) {
671
673
674
+ if (property .isIdProperty () && ((Document ) target ).hasId ()) {
675
+ return ((Document ) target ).getId ();
676
+ }
677
+
678
+ if (property .isVersionProperty () && ((Document ) target ).hasVersion ()) {
679
+ return ((Document ) target ).getVersion ();
680
+ }
681
+
682
+ if (property .isScoreProperty ()) {
683
+ return ((SearchDocument ) target ).getScore ();
684
+ }
685
+
672
686
String fieldName = property .getFieldName ();
673
687
674
688
if (!fieldName .contains ("." )) {
@@ -691,6 +705,19 @@ public Object get(ElasticsearchPersistentProperty property) {
691
705
return result ;
692
706
}
693
707
708
+ public void set (ElasticsearchPersistentProperty property , Object value ) {
709
+
710
+ if (property .isIdProperty ()) {
711
+ ((Document ) target ).setId ((String ) value );
712
+ }
713
+
714
+ if (property .isVersionProperty ()) {
715
+ ((Document ) target ).setVersion ((Long ) value );
716
+ }
717
+
718
+ target .put (property .getFieldName (), value );
719
+ }
720
+
694
721
@ SuppressWarnings ("unchecked" )
695
722
private Map <String , Object > getAsMap (Object result ) {
696
723
0 commit comments