~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to solr/core/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.solr.search.function.distance;
2
 
/**
3
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
4
 
 * contributor license agreements.  See the NOTICE file distributed with
5
 
 * this work for additional information regarding copyright ownership.
6
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
7
 
 * (the "License"); you may not use this file except in compliance with
8
 
 * the License.  You may obtain a copy of the License at
9
 
 *
10
 
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 
 *
12
 
 * Unless required by applicable law or agreed to in writing, software
13
 
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 
 * See the License for the specific language governing permissions and
16
 
 * limitations under the License.
17
 
 */
18
 
 
19
 
import org.apache.lucene.spatial.geohash.GeoHashUtils;
20
 
import org.apache.lucene.spatial.DistanceUtils;
21
 
import org.apache.solr.SolrTestCaseJ4;
22
 
import org.apache.solr.common.SolrException;
23
 
import org.junit.BeforeClass;
24
 
import org.junit.Test;
25
 
 
26
 
/**
27
 
 *
28
 
 *
29
 
 **/
30
 
public class DistanceFunctionTest extends SolrTestCaseJ4 {
31
 
  @BeforeClass
32
 
  public static void beforeClass() throws Exception {
33
 
    initCore("solrconfig.xml", "schema12.xml");
34
 
  }
35
 
 
36
 
  @Test
37
 
  public void testHaversine() throws Exception {
38
 
    clearIndex();
39
 
    assertU(adoc("id", "1", "x_td", "0", "y_td", "0", "gh_s1", GeoHashUtils.encode(32.7693246, -79.9289094)));
40
 
    assertU(adoc("id", "2", "x_td", "0", "y_td", String.valueOf(Math.PI / 2), "gh_s1", GeoHashUtils.encode(32.7693246, -78.9289094)));
41
 
    assertU(adoc("id", "3", "x_td", String.valueOf(Math.PI / 2), "y_td", String.valueOf(Math.PI / 2), "gh_s1", GeoHashUtils.encode(32.7693246, -80.9289094)));
42
 
    assertU(adoc("id", "4", "x_td", String.valueOf(Math.PI / 4), "y_td", String.valueOf(Math.PI / 4), "gh_s1", GeoHashUtils.encode(32.7693246, -81.9289094)));
43
 
    assertU(adoc("id", "5", "x_td", "45.0", "y_td", "45.0",
44
 
            "gh_s1", GeoHashUtils.encode(32.7693246, -81.9289094)));
45
 
    assertU(adoc("id", "6", "point_hash", "32.5, -79.0", "point", "32.5, -79.0"));
46
 
    assertU(adoc("id", "7", "point_hash", "32.6, -78.0", "point", "32.6, -78.0"));
47
 
    assertU(commit());
48
 
    //Get the haversine distance between the point 0,0 and the docs above assuming a radius of 1
49
 
    assertQ(req("fl", "*,score", "q", "{!func}hsin(1, false, x_td, y_td, 0, 0)", "fq", "id:1"), "//float[@name='score']='0.0'");
50
 
    assertQ(req("fl", "*,score", "q", "{!func}hsin(1, false, x_td, y_td, 0, 0)", "fq", "id:2"), "//float[@name='score']='" + (float) (Math.PI / 2) + "'");
51
 
    assertQ(req("fl", "*,score", "q", "{!func}hsin(1, false, x_td, y_td, 0, 0)", "fq", "id:3"), "//float[@name='score']='" + (float) (Math.PI / 2) + "'");
52
 
    assertQ(req("fl", "*,score", "q", "{!func}hsin(1, false, x_td, y_td, 0, 0)", "fq", "id:4"), "//float[@name='score']='1.0471976'");
53
 
    assertQ(req("fl", "*,score", "q", "{!func}hsin(1, true, x_td, y_td, 0, 0)", "fq", "id:5"), "//float[@name='score']='1.0471976'");
54
 
    //SOLR-2114
55
 
    assertQ(req("fl", "*,score", "q", "{!func}hsin(6371.009, true, point, vector(0, 0))", "fq", "id:6"), "//float[@name='score']='8977.814'");
56
 
    
57
 
    //Geo Hash Haversine
58
 
    //Can verify here: http://www.movable-type.co.uk/scripts/latlong.html, but they use a slightly different radius for the earth, so just be close
59
 
    assertQ(req("fl", "*,score", "q", "{!func}ghhsin(" + DistanceUtils.EARTH_MEAN_RADIUS_KM + ", gh_s1, \"" + GeoHashUtils.encode(32, -79) +
60
 
            "\",)", "fq", "id:1"), "//float[@name='score']='122.171875'");
61
 
 
62
 
    assertQ(req("fl", "id,point_hash,score", "q", "{!func}recip(ghhsin(" + DistanceUtils.EARTH_MEAN_RADIUS_KM + ", point_hash, \"" + GeoHashUtils.encode(32, -79) + "\"), 1, 1, 0)"),
63
 
            "//*[@numFound='7']", 
64
 
            "//result/doc[1]/str[@name='id'][.='6']",
65
 
            "//result/doc[2]/str[@name='id'][.='7']"//all the rest don't matter
66
 
            );
67
 
 
68
 
 
69
 
    assertQ(req("fl", "*,score", "q", "{!func}ghhsin(" + DistanceUtils.EARTH_MEAN_RADIUS_KM + ", gh_s1, geohash(32, -79))", "fq", "id:1"), "//float[@name='score']='122.171875'");
70
 
  }
71
 
 
72
 
 
73
 
  @Test
74
 
  public void testLatLon() throws Exception {
75
 
    assertU(adoc("id", "100", "store", "1,2"));
76
 
    assertU(commit());
77
 
   
78
 
    assertJQ(req("defType","func", 
79
 
                 "q","geodist(1,2,3,4)",
80
 
                 "fq","id:100",
81
 
                 "fl","id,score")
82
 
             , 1e-5
83
 
             , "/response/docs/[0]/score==314.40338"
84
 
             );
85
 
 
86
 
    // throw in some decimal points
87
 
    assertJQ(req("defType","func", 
88
 
                 "q","geodist(1.0,2,3,4.0)",
89
 
                 "fq","id:100",
90
 
                 "fl","id,score")
91
 
             , 1e-5
92
 
             , "/response/docs/[0]/score==314.40338"
93
 
             );
94
 
 
95
 
    // default to reading pt
96
 
    assertJQ(req("defType","func", 
97
 
                 "q","geodist(1,2)",
98
 
                 "pt","3,4", 
99
 
                 "fq","id:100",
100
 
                 "fl","id,score")
101
 
             , 1e-5
102
 
             , "/response/docs/[0]/score==314.40338"
103
 
             );
104
 
 
105
 
    // default to reading pt first
106
 
    assertJQ(req("defType","func", 
107
 
                 "q","geodist(1,2)",
108
 
                 "pt","3,4", 
109
 
                 "sfield","store", 
110
 
                 "fq","id:100",
111
 
                 "fl","id,score")
112
 
             , 1e-5
113
 
             , "/response/docs/[0]/score==314.40338"
114
 
             );
115
 
 
116
 
    // if pt missing, use sfield
117
 
    assertJQ(req("defType","func", 
118
 
                 "q","geodist(3,4)",
119
 
                 "sfield","store", 
120
 
                 "fq","id:100",
121
 
                 "fl","id,score")
122
 
             , 1e-5
123
 
             ,"/response/docs/[0]/score==314.40338"
124
 
             );
125
 
    
126
 
    // read both pt and sfield
127
 
    assertJQ(req("defType","func", 
128
 
                 "q","geodist()","pt","3,4",
129
 
                 "sfield","store", 
130
 
                 "fq","id:100",
131
 
                 "fl","id,score")
132
 
             , 1e-5
133
 
             ,"/response/docs/[0]/score==314.40338"
134
 
             );
135
 
 
136
 
    // param substitution
137
 
    assertJQ(req("defType","func", 
138
 
                 "q","geodist($a,$b)",
139
 
                 "a","3,4",
140
 
                 "b","store", 
141
 
                 "fq","id:100",
142
 
                 "fl","id,score")
143
 
             , 1e-5
144
 
             ,"/response/docs/[0]/score==314.40338"
145
 
             );
146
 
 
147
 
  }
148
 
 
149
 
  
150
 
  @Test
151
 
  public void testVector() throws Exception {
152
 
    clearIndex();
153
 
    assertU(adoc("id", "1", "x_td", "0", "y_td", "0", "z_td", "0", "w_td", "0"));
154
 
    assertU(adoc("id", "2", "x_td", "0", "y_td", "1", "z_td", "0", "w_td", "0"));
155
 
    assertU(adoc("id", "3", "x_td", "1", "y_td", "1", "z_td", "1", "w_td", "1"));
156
 
    assertU(adoc("id", "4", "x_td", "1", "y_td", "0", "z_td", "0", "w_td", "0"));
157
 
    assertU(adoc("id", "5", "x_td", "2.3", "y_td", "5.5", "z_td", "7.9", "w_td", "-2.4"));
158
 
    assertU(adoc("id", "6", "point", "1.0,0.0"));
159
 
    assertU(adoc("id", "7", "point", "5.5,10.9"));
160
 
    assertU(commit());
161
 
    //two dimensions, notice how we only pass in 4 value sources
162
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, 0, 0)", "fq", "id:1"), "//float[@name='score']='0.0'");
163
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, 0, 0)", "fq", "id:2"), "//float[@name='score']='1.0'");
164
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, 0, 0)", "fq", "id:3"), "//float[@name='score']='" + 2.0f + "'");
165
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, 0, 0)", "fq", "id:4"), "//float[@name='score']='1.0'");
166
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, 0, 0)", "fq", "id:5"), "//float[@name='score']='" + (float) (2.3 * 2.3 + 5.5 * 5.5) + "'");
167
 
 
168
 
    //three dimensions, notice how we pass in 6 value sources
169
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, 0, 0, 0)", "fq", "id:1"), "//float[@name='score']='0.0'");
170
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, 0, 0, 0)", "fq", "id:2"), "//float[@name='score']='1.0'");
171
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, 0, 0, 0)", "fq", "id:3"), "//float[@name='score']='" + 3.0f + "'");
172
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, 0, 0, 0)", "fq", "id:4"), "//float[@name='score']='1.0'");
173
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, 0, 0, 0)", "fq", "id:5"), "//float[@name='score']='" + (float) (2.3 * 2.3 + 5.5 * 5.5 + 7.9 * 7.9) + "'");
174
 
 
175
 
    //four dimensions, notice how we pass in 8 value sources
176
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, w_td, 0, 0, 0, 0)", "fq", "id:1"), "//float[@name='score']='0.0'");
177
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, w_td, 0, 0, 0, 0)", "fq", "id:2"), "//float[@name='score']='1.0'");
178
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, w_td, 0, 0, 0, 0)", "fq", "id:3"), "//float[@name='score']='" + 4.0f + "'");
179
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, w_td, 0, 0, 0, 0)", "fq", "id:4"), "//float[@name='score']='1.0'");
180
 
    assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, w_td, 0, 0, 0, 0)", "fq", "id:5"), "//float[@name='score']='" + (float) (2.3 * 2.3 + 5.5 * 5.5 + 7.9 * 7.9 + 2.4 * 2.4) + "'");
181
 
    //Pass in imbalanced list, throw exception
182
 
    try {
183
 
      ignoreException("Illegal number of sources");
184
 
      assertQ(req("fl", "*,score", "q", "{!func}sqedist(x_td, y_td, z_td, w_td, 0, 0, 0)", "fq", "id:1"), "//float[@name='score']='0.0'");
185
 
      assertTrue("should throw an exception", false);
186
 
    } catch (Exception e) {
187
 
      Throwable cause = e.getCause();
188
 
      assertNotNull(cause);
189
 
      assertTrue(cause instanceof SolrException);
190
 
    }
191
 
    resetExceptionIgnores();
192
 
 
193
 
    //do one test of Euclidean
194
 
    //two dimensions, notice how we only pass in 4 value sources
195
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(2, x_td, y_td, 0, 0)", "fq", "id:1"), "//float[@name='score']='0.0'");
196
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(2, x_td, y_td, 0, 0)", "fq", "id:2"), "//float[@name='score']='1.0'");
197
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(2, x_td, y_td, 0, 0)", "fq", "id:3"), "//float[@name='score']='" + (float) Math.sqrt(2.0) + "'");
198
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(2, x_td, y_td, 0, 0)", "fq", "id:4"), "//float[@name='score']='1.0'");
199
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(2, x_td, y_td, 0, 0)", "fq", "id:5"), "//float[@name='score']='" + (float) Math.sqrt((2.3 * 2.3 + 5.5 * 5.5)) + "'");
200
 
 
201
 
    //do one test of Manhattan
202
 
    //two dimensions, notice how we only pass in 4 value sources
203
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(1, x_td, y_td, 0, 0)", "fq", "id:1"), "//float[@name='score']='0.0'");
204
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(1, x_td, y_td, 0, 0)", "fq", "id:2"), "//float[@name='score']='1.0'");
205
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(1, x_td, y_td, 0, 0)", "fq", "id:3"), "//float[@name='score']='" + (float) 2.0 + "'");
206
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(1, x_td, y_td, 0, 0)", "fq", "id:4"), "//float[@name='score']='1.0'");
207
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(1, x_td, y_td, 0, 0)", "fq", "id:5"), "//float[@name='score']='" + (float) (2.3 + 5.5) + "'");
208
 
 
209
 
 
210
 
    //Do point tests:
211
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(1, vector(x_td, y_td), vector(0, 0))", "fq", "id:5"),
212
 
            "//float[@name='score']='" + (float) (2.3 + 5.5) + "'");
213
 
 
214
 
    assertQ(req("fl", "*,score", "q", "{!func}dist(1, point, vector(0, 0))", "fq", "id:6"),
215
 
            "//float[@name='score']='" + 1.0f + "'");
216
 
 
217
 
  }
218
 
 
219
 
}