Project

General

Profile

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

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

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

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

    
46
    public static String NULL_STRING = "";
47

    
48

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

    
57
    /* (non-Javadoc)
58
     * @see org.hibernate.search.bridge.FieldBridge#set(java.lang.String, java.lang.Object, org.apache.lucene.document.Document, org.hibernate.search.bridge.LuceneOptions)
59
     */
60
    @Override
61
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
62

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

    
74
        Field field = new StringField(
75
                name,
76
                String.valueOf(value.toString()),
77
                luceneOptions.getStore());
78
        document.add(field);
79

    
80
        Field sort_field = new SortedDocValuesField(
81
                name + "__sort",
82
                new BytesRef(value.toString()));
83
        LuceneDocumentUtility.setOrReplaceDocValueField(sort_field, document);
84

    
85
        Field notNullField = new StringField(
86
                notNullField(name),
87
                String.valueOf(NOT_NULL_VALUE),
88
                Store.NO
89
                );
90
        document.add(notNullField);
91
    }
92

    
93
    @Override
94
    public Object get(String name, Document document) {
95
        return document.get(name);
96
    }
97

    
98
    /* (non-Javadoc)
99
     * @see org.hibernate.search.bridge.TwoWayFieldBridge#objectToString(java.lang.Object)
100
     */
101
    @Override
102
    public String objectToString(Object object) {
103
        if(object == null){
104
            return NULL_STRING;
105
        } else {
106
            return object.toString();
107
        }
108
    }
109

    
110
}
(13-13/18)