Project

General

Profile

Download (3.53 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2012 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.hibernate.search;
10

    
11
import org.apache.lucene.document.Document;
12
import org.apache.lucene.document.Field;
13
import org.apache.lucene.document.Field.Index;
14
import org.apache.lucene.document.Field.Store;
15
import org.apache.lucene.document.Field.TermVector;
16
import org.apache.lucene.document.SortedDocValuesField;
17
import org.apache.lucene.document.StringField;
18
import org.apache.lucene.util.BytesRef;
19
import org.hibernate.search.bridge.LuceneOptions;
20
import org.hibernate.search.bridge.TwoWayFieldBridge;
21

    
22
/**
23
 * This {@link TwoWayFieldBridge} allows to efficiently query for associated
24
 * entities which are not null. This field bridge works the following way:
25
 * <p>
26
 * It adds the id field to the document as if it would be done without the
27
 * intervention of this class, all field attributes are preserved, additionally
28
 * this field bridge also adds a field named <code>id.notNull</code> and stores
29
 * the term "true" for this field. So all associated entities which are not null
30
 * can now be queried by searching for <code>+id.notNull:true</code> which is
31
 * much more efficient than using range queries.
32
 * <p>
33
 * The <code>id.notNull</code> is stored with the following attributes :
34
 * {@link Store.NO},{@link Index.NOT_ANALYZED}, {@link TermVector.NO}.
35
 *
36
 * @author a.kohlbecker
37
 * @since Sep 21, 2012
38
 *
39
 */
40
public class NotNullAwareIdBridge implements TwoWayFieldBridge {
41

    
42
    public static final String NOT_NULL_VALUE = "1";
43
    public static final String NOT_NULL_FIELD_NAME = "notNull";
44

    
45
    public static String NULL_STRING = "";
46

    
47

    
48
    /**
49
     * @param name
50
     * @return
51
     */
52
    public static String notNullField(String name) {
53
        return name + "." + NOT_NULL_FIELD_NAME;
54
    }
55

    
56
    @Override
57
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
58

    
59
        /*
60
         * DocumentBuilderIndexedEntity<T>.buildDocumentFields(Object, Document, PropertiesMetadata, Map<String,String>, Set<String>)
61
         * is adding the idField a second time even if it has already been set by an idFieldBrige. this might be fixed in a
62
         * more recent version of hibernate! TODO after hibernate update: check if we can remove this extra condition.
63
         * We are avoiding this by checking the document:
64
         *
65
         */
66
        if(name.endsWith("id") && document.getField(name) != null) { // id already set?
67
            return;
68
        }
69

    
70
        Field field = new StringField(
71
                name,
72
                String.valueOf(value.toString()),
73
                luceneOptions.getStore());
74
        document.add(field);
75

    
76
        Field sort_field = new SortedDocValuesField(
77
                name + "__sort",
78
                new BytesRef(value.toString()));
79
        LuceneDocumentUtility.setOrReplaceDocValueField(sort_field, document);
80

    
81
        Field notNullField = new StringField(
82
                notNullField(name),
83
                String.valueOf(NOT_NULL_VALUE),
84
                Store.NO
85
                );
86
        document.add(notNullField);
87
    }
88

    
89
    @Override
90
    public Object get(String name, Document document) {
91
        return document.get(name);
92
    }
93

    
94
    @Override
95
    public String objectToString(Object object) {
96
        if(object == null){
97
            return NULL_STRING;
98
        } else {
99
            return object.toString();
100
        }
101
    }
102

    
103
}
(13-13/19)