Skip to content

Commit a898782

Browse files
authored
Merge pull request #395 from ml054/v5.4
v5.2 to v5.4 merge
2 parents 590e82f + 29f28d5 commit a898782

File tree

3 files changed

+187
-8
lines changed

3 files changed

+187
-8
lines changed

src/Documents/Session/AbstractDocumentQuery.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ export abstract class AbstractDocumentQuery<T extends object, TSelf extends Abst
12681268
* <p>
12691269
* 0.0 to 1.0 where 1.0 means closer match
12701270
* <p>
1271-
* http://lucene.apache.org/java/2_4_0/queryparsersyntax.html#Fuzzy%20Searches
1271+
* https://lucene.apache.org/core/2_9_4/queryparsersyntax.html#Fuzzy%20Searches
12721272
*/
12731273
public _fuzzy(fuzzy: number): void {
12741274
const tokens = this._getCurrentWhereTokens();
@@ -1294,9 +1294,9 @@ export abstract class AbstractDocumentQuery<T extends object, TSelf extends Abst
12941294
}
12951295

12961296
/**
1297-
* Specifies a proximity distance for the phrase in the last where clause
1297+
* Specifies a proximity distance for the phrase in the last search clause
12981298
* <p>
1299-
* http://lucene.apache.org/java/2_4_0/queryparsersyntax.html#Proximity%20Searches
1299+
* https://lucene.apache.org/core/2_9_4/queryparsersyntax.html#Proximity%20Searches
13001300
*/
13011301
public _proximity(proximity: number): void {
13021302
const tokens = this._getCurrentWhereTokens();
@@ -1311,11 +1311,11 @@ export abstract class AbstractDocumentQuery<T extends object, TSelf extends Abst
13111311

13121312
if ((whereToken as WhereToken).whereOperator !== "Search" as WhereOperator) {
13131313
throwError("InvalidOperationException",
1314-
"Fuzzy can only be used right after where clause with equals operator");
1314+
"Proximity can only be used right after search clause");
13151315
}
13161316

1317-
if (proximity < 1) {
1318-
throwError("InvalidArgumentException", "Proximity distance must be a positive number.");
1317+
if (proximity < 0) {
1318+
throwError("InvalidArgumentException", "Proximity distance must be a number greater than or equal to 0");
13191319
}
13201320

13211321
(whereToken as WhereToken).options.proximity = proximity;

src/Documents/Session/IDocumentQueryBase.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export interface IDocumentQueryBase<T extends object, TSelf extends IDocumentQue
5555
* Specifies a fuzziness factor to the single word term in the last where clause
5656
* 0.0 to 1.0 where 1.0 means closer match
5757
*
58-
* http://lucene.apache.org/java/2_4_0/queryparsersyntax.html#Fuzzy%20Searches
58+
* https://lucene.apache.org/core/2_9_4/queryparsersyntax.html#Fuzzy%20Searches
5959
*/
6060
fuzzy(fuzzy: number): TSelf;
6161

@@ -131,7 +131,7 @@ export interface IDocumentQueryBase<T extends object, TSelf extends IDocumentQue
131131

132132
/**
133133
* Specifies a proximity distance for the phrase in the last search clause
134-
* http://lucene.apache.org/java/2_4_0/queryparsersyntax.html#Proximity%20Searches
134+
* https://lucene.apache.org/core/2_9_4/queryparsersyntax.html#Proximity%20Searches
135135
*/
136136
proximity(proximity: number): TSelf;
137137

test/Ported/Issues/RDBC_751.ts

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import { IDocumentStore } from "../../../src/Documents/IDocumentStore";
2+
import { disposeTestDocumentStore, testContext } from "../../Utils/TestUtil";
3+
import { Employee} from "../../Assets/Orders";
4+
import {assertThat, assertThrows} from "../../Utils/AssertExtensions";
5+
import DocumentStore from "../../../src";
6+
import {CreateSampleDataOperation} from "../../Utils/CreateSampleDataOperation";
7+
8+
describe("RDBC_751", function () {
9+
let regularStore: IDocumentStore;
10+
11+
beforeEach(async function () {
12+
regularStore = await testContext.getDocumentStore();
13+
});
14+
15+
afterEach(async () =>
16+
await disposeTestDocumentStore(regularStore));
17+
18+
function getStoreWithCustomConventions(setupStore: (store: DocumentStore) => void) {
19+
const customStore = new DocumentStore(regularStore.urls, regularStore.database);
20+
setupStore(customStore);
21+
customStore.initialize();
22+
return customStore;
23+
}
24+
25+
it("canSearchWithProximityZero", async () => {
26+
let store: DocumentStore;
27+
28+
try {
29+
store = getStoreWithCustomConventions((s) => {
30+
s.conventions.findCollectionNameForObjectLiteral = (o) => o["collection"];
31+
s.conventions.entityFieldNameConvention = "camel";
32+
s.conventions.remoteEntityFieldNameConvention = "pascal";
33+
s.conventions.identityProperty = "id";
34+
s.conventions.registerEntityIdPropertyName(Object, "id");
35+
});
36+
37+
await store.maintenance.send(new CreateSampleDataOperation());
38+
39+
{
40+
const session = store.openSession();
41+
42+
const employee9A = await session.load<Employee>("employees/9-A");
43+
employee9A.notes = ["Anne has a BA degree in English from St. Lawrence College. She has fluent French."];
44+
await session.store(employee9A);
45+
await session.saveChanges();
46+
}
47+
48+
// Test for terms that are maximum 5 terms apart
49+
{
50+
const session = store.openSession();
51+
52+
const employeesWithProximity5 = await session
53+
.query(Employee)
54+
.search("Notes", "fluent french")
55+
.proximity(5)
56+
.waitForNonStaleResults()
57+
.all();
58+
59+
assertThat(employeesWithProximity5).hasSize(4);
60+
}
61+
62+
// Test for terms that are 0 terms apart
63+
// Results will contain a single word that was not tokenized to a term in between
64+
{
65+
const session = store.openSession();
66+
67+
const employeesWithProximity0 = await session
68+
.query(Employee)
69+
.search("Notes", "fluent french")
70+
.proximity(0)
71+
.waitForNonStaleResults()
72+
.all();
73+
74+
assertThat(employeesWithProximity0).hasSize(3);
75+
76+
assertThat(employeesWithProximity0[0].id).isEqualTo("employees/2-A");
77+
assertThat(employeesWithProximity0[1].id).isEqualTo("employees/5-A");
78+
assertThat(employeesWithProximity0[2].id).isEqualTo("employees/9-A");
79+
80+
assertThat(employeesWithProximity0[0].notes[0]).contains("fluent in French");
81+
assertThat(employeesWithProximity0[1].notes[0]).contains("fluent in French");
82+
assertThat(employeesWithProximity0[2].notes[0]).contains("fluent French");
83+
}
84+
85+
// Test that are 0 terms apart
86+
// Consecutive results only
87+
{
88+
const session = store.openSession();
89+
90+
const employee2A = await session.load<Employee>("employees/2-A");
91+
employee2A.notes = ["Andrew knows fluent Belgian French."];
92+
await session.store(employee2A);
93+
94+
const employee5A = await session.load<Employee>("employees/5-A");
95+
employee5A.notes = ["Steven knows fluent Canadian French."];
96+
await session.store(employee5A);
97+
98+
await session.saveChanges();
99+
100+
const employeesWithProximity0 = await session
101+
.query(Employee)
102+
.search("Notes", "fluent french")
103+
.proximity(0)
104+
.waitForNonStaleResults()
105+
.all()
106+
107+
assertThat(employeesWithProximity0).hasSize(1);
108+
assertThat(employeesWithProximity0[0].id).isEqualTo("employees/9-A");
109+
}
110+
111+
} finally {
112+
store.dispose();
113+
}
114+
});
115+
116+
it("cannotSearchWithNegativeProximity", async () => {
117+
const session = regularStore.openSession();
118+
119+
await assertThrows(
120+
async () => await session
121+
.query(Employee)
122+
.search("Notes", "fluent french")
123+
.proximity(-1)
124+
.waitForNonStaleResults()
125+
.all(),
126+
err => {
127+
assertThat(err.name).isEqualTo("InvalidArgumentException");
128+
assertThat(err.message).isEqualTo("Proximity distance must be a number greater than or equal to 0");
129+
});
130+
});
131+
132+
it("cannotUseProximityAfterWhereClause", async () => {
133+
const session = regularStore.openSession();
134+
135+
await assertThrows(
136+
async () => await session
137+
.query(Employee)
138+
.whereEquals("Notes", "fluent french")
139+
.proximity(1)
140+
.waitForNonStaleResults()
141+
.all(),
142+
err => {
143+
assertThat(err.name).isEqualTo("InvalidOperationException");
144+
assertThat(err.message).isEqualTo("Proximity can only be used right after search clause");
145+
});
146+
});
147+
148+
it("CannotUseProximityWithSingleTerm", async () => {
149+
const session = regularStore.openSession();
150+
151+
await assertThrows(
152+
async () => await session
153+
.query(Employee)
154+
.search("Notes", "fluent")
155+
.proximity(1)
156+
.waitForNonStaleResults()
157+
.all(),
158+
err => {
159+
assertThat(err.name).isEqualTo("InvalidQueryException");
160+
assertThat(err.message).contains("Proximity search works only on multiple search terms");
161+
});
162+
});
163+
164+
it("CannotUseProximityWithWildcards", async () => {
165+
const session = regularStore.openSession();
166+
167+
await assertThrows(
168+
async () => await session
169+
.query(Employee)
170+
.search("Notes", "*luent frenc*")
171+
.proximity(1)
172+
.waitForNonStaleResults()
173+
.all(),
174+
err => {
175+
assertThat(err.name).isEqualTo("InvalidQueryException");
176+
assertThat(err.message).contains("Proximity search works only on simple string terms, not wildcard");
177+
});
178+
});
179+
});

0 commit comments

Comments
 (0)