Skip to content

Commit 1c5a237

Browse files
MarkDuckworththiyaguk09
authored andcommitted
feat(firestore): Added search stage support for languageCode, offset, limit, and retrievalDepth (googleapis#8161)
1 parent 6fcf9b9 commit 1c5a237

4 files changed

Lines changed: 153 additions & 119 deletions

File tree

handwritten/firestore/dev/src/pipelines/expression.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3256,7 +3256,7 @@ export abstract class Expression
32563256
// * Evaluates to an HTML-formatted text snippet that renders terms matching
32573257
// * the search query in `<b>bold</b>`.
32583258
// *
3259-
// * @remarks This Expression can only be used within a `Search` stage.
3259+
// * @remarks This Expression can only be used within a `search` stage.
32603260
// *
32613261
// * @param rquery Define the search query using the search domain-specific language (DSL).
32623262
// * @returns An `Expression` representing the snippet function.
@@ -3267,7 +3267,7 @@ export abstract class Expression
32673267
// * Evaluates to an HTML-formatted text snippet that renders terms matching
32683268
// * the search query in `<b>bold</b>`.
32693269
// *
3270-
// * @remarks This Expression can only be used within a `Search` stage.
3270+
// * @remarks This Expression can only be used within a `search` stage.
32713271
// *
32723272
// * @param options Define how snippeting behaves.
32733273
// * @returns An `Expression` representing the snippet function.
@@ -3543,7 +3543,7 @@ export class Field
35433543
// /**
35443544
// * Perform a full-text search on this field.
35453545
// *
3546-
// * @remarks This Expression can only be used within a `Search` stage.
3546+
// * @remarks This Expression can only be used within a `search` stage.
35473547
// *
35483548
// * @param rquery Define the search query using the search domain-specific language (DSL).
35493549
// * @returns A `BooleanExpression` representing the matches function.
@@ -3561,7 +3561,7 @@ export class Field
35613561
* Evaluates to the distance in meters between the location specified
35623562
* by this field and the query location.
35633563
*
3564-
* @remarks This Expression can only be used within a `Search` stage.
3564+
* @remarks This Expression can only be used within a `search` stage.
35653565
*
35663566
* @example
35673567
* ```typescript
@@ -10678,7 +10678,7 @@ export function isType(
1067810678
// * @beta
1067910679
// * Perform a full-text search on the specified field.
1068010680
// *
10681-
// * @remarks This Expression can only be used within a `Search` stage.
10681+
// * @remarks This Expression can only be used within a `search` stage.
1068210682
// *
1068310683
// * @param searchField Search the specified field.
1068410684
// * @param rquery Define the search query using the search domain-specific language (DSL).
@@ -10696,7 +10696,7 @@ export function isType(
1069610696
*
1069710697
* Perform a full-text search on the document.
1069810698
*
10699-
* @remarks This Expression can only be used within a `Search` stage.
10699+
* @remarks This Expression can only be used within a `search` stage.
1070010700
*
1070110701
* @param rquery Define the search query using the search domain-specific language (DSL).
1070210702
* @returns A `BooleanExpression` representing the documentMatches function.
@@ -10717,7 +10717,7 @@ export function documentMatches(
1071710717
* in the search `query` provided to the `search` stage. If the `query` provided to the search stage
1071810718
* is not set or does not contain any text predicates, then this score will always be `0`.
1071910719
*
10720-
* @remarks This Expression can only be used within a `Search` stage.
10720+
* @remarks This Expression can only be used within a `search` stage.
1072110721
*
1072210722
* @returns An `Expression` representing the score function.
1072310723
*/
@@ -10729,7 +10729,7 @@ export function score(): Expression {
1072910729
// * Evaluates to an HTML-formatted text snippet that highlights terms matching
1073010730
// * the search query in `<b>bold</b>`.
1073110731
// *
10732-
// * @remarks This Expression can only be used within a `Search` stage.
10732+
// * @remarks This Expression can only be used within a `search` stage.
1073310733
// *
1073410734
// * @param searchField Search the specified field for matching terms.
1073510735
// * @param rquery Define the search query using the search domain-specific language (DSL).
@@ -10744,7 +10744,7 @@ export function score(): Expression {
1074410744
// * Evaluates to an HTML-formatted text snippet that highlights terms matching
1074510745
// * the search query in `<b>bold</b>`.
1074610746
// *
10747-
// * @remarks This Expression can only be used within a `Search` stage.
10747+
// * @remarks This Expression can only be used within a `search` stage.
1074810748
// *
1074910749
// * @param searchField Search the specified field for matching terms.
1075010750
// * @param options Define the search query using the search domain-specific language (DSL).
@@ -10769,7 +10769,7 @@ export function score(): Expression {
1076910769
* Evaluates to the distance in meters between the location in the specified
1077010770
* field and the query location.
1077110771
*
10772-
* @remarks This Expression can only be used within a `Search` stage.
10772+
* @remarks This Expression can only be used within a `search` stage.
1077310773
*
1077410774
* @param fieldName - Specifies the field in the document which contains
1077510775
* the first GeoPoint for distance computation.

handwritten/firestore/dev/system-test/pipeline.ts

Lines changed: 97 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6561,68 +6561,104 @@ describe.skipClassic('Pipeline search', () => {
65616561
// });
65626562
});
65636563

6564-
// TODO(search) enable with backend support
6565-
// describe('limit', () => {
6566-
// it('limits the number of documents returned', async () => {
6567-
// const ppl = firestore
6568-
// .pipeline()
6569-
// .collection(COLLECTION_NAME)
6570-
// .search({
6571-
// query: constant(true),
6572-
// sort: field('location')
6573-
// .geoDistance(new GeoPoint(39.6985, -105.024))
6574-
// .ascending(),
6575-
// limit: 5,
6576-
// queryEnhancement: 'disabled',
6577-
// });
6578-
//
6579-
// const snapshot = await ppl.execute();
6580-
// expectResults(
6581-
// snapshot,
6582-
// 'solTacos',
6583-
// 'lotusBlossomThai',
6584-
// 'goldenWaffle',
6585-
// );
6586-
// });
6587-
// it('limits the number of documents scored', async () => {
6588-
// const ppl = firestore
6589-
// .pipeline()
6590-
// .collection(COLLECTION_NAME)
6591-
// .search({
6592-
// query: field('menu').matches(
6593-
// 'chicken OR tacos OR fish OR waffles',
6594-
// ),
6595-
// retrievalDepth: 6,
6596-
// queryEnhancement: 'disabled',
6597-
// });
6598-
//
6599-
// const snapshot = await ppl.execute();
6600-
// expectResults(
6601-
// snapshot,
6602-
// 'eastsideChicken',
6603-
// 'eastsideTacos',
6604-
// 'solTacos',
6605-
// 'mileHighCatch',
6606-
// );
6607-
// });
6608-
// });
6564+
describe('languageCode', () => {
6565+
const rquery = 'al pastor';
6566+
it('en', async () => {
6567+
const ppl = firestore
6568+
.pipeline()
6569+
.collection(COLLECTION_NAME)
6570+
.search({
6571+
query: documentMatches(rquery),
6572+
sort: score().descending(),
6573+
languageCode: 'en',
6574+
// queryEnhancement: 'disabled'
6575+
});
66096576

6610-
// TODO(search) enable with backend support
6611-
// describe('offset', () => {
6612-
// it('skips N documents', async () => {
6613-
// const ppl = firestore
6614-
// .pipeline()
6615-
// .collection(COLLECTION_NAME)
6616-
// .search({
6617-
// query: constant(true),
6618-
// limit: 2,
6619-
// offset: 2,
6620-
// queryEnhancement: 'disabled',
6621-
// });
6622-
//
6623-
// const snapshot = await ppl.execute();
6624-
// expectResults(snapshot, 'eastsideChicken', 'eastsideTacos');
6625-
// });
6577+
const snapshot = await ppl.execute();
6578+
expectResults(snapshot, 'solTacos');
6579+
});
6580+
6581+
it('unknown', async () => {
6582+
const ppl = firestore
6583+
.pipeline()
6584+
.collection(COLLECTION_NAME)
6585+
.search({
6586+
query: documentMatches(rquery),
6587+
sort: score().descending(),
6588+
languageCode: 'unknown',
6589+
// queryEnhancement: 'disabled'
6590+
});
6591+
6592+
await expect(ppl.execute()).to.be.rejectedWith(
6593+
/3 INVALID_ARGUMENT.*/,
6594+
);
6595+
});
6596+
});
6597+
6598+
describe('limit', () => {
6599+
it('limits the number of documents returned', async () => {
6600+
const ppl = firestore
6601+
.pipeline()
6602+
.collection(COLLECTION_NAME)
6603+
.search({
6604+
query: field('location')
6605+
.geoDistance(new GeoPoint(39.6985, -105.024))
6606+
.lessThanOrEqual(100000000),
6607+
sort: field('location')
6608+
.geoDistance(new GeoPoint(39.6985, -105.024))
6609+
.ascending(),
6610+
limit: 3,
6611+
// queryEnhancement: 'disabled'
6612+
});
6613+
6614+
const snapshot = await ppl.execute();
6615+
expectResults(
6616+
snapshot,
6617+
'solTacos',
6618+
'lotusBlossomThai',
6619+
'mileHighCatch',
6620+
);
6621+
});
6622+
6623+
it('limits the number of documents scored via retrievalDepth', async () => {
6624+
const commonSearchParams = {
6625+
query: documentMatches('taco'),
6626+
addFields: [score().as('score')],
6627+
sort: score().descending(),
6628+
// queryEnhancement: 'disabled' as QueryEnhancement
6629+
};
6630+
6631+
let ppl = firestore
6632+
.pipeline()
6633+
.collection(COLLECTION_NAME)
6634+
.search({...commonSearchParams, retrievalDepth: 2});
6635+
6636+
let snapshot = await ppl.execute();
6637+
expectResults(snapshot, 'solTacos', 'eastsideTacos');
6638+
6639+
ppl = firestore
6640+
.pipeline()
6641+
.collection(COLLECTION_NAME)
6642+
.search({...commonSearchParams, retrievalDepth: 1});
6643+
6644+
snapshot = await ppl.execute();
6645+
expectResults(snapshot, 'eastsideTacos');
6646+
});
6647+
});
6648+
6649+
describe('offset', () => {
6650+
it('skips N documents', async () => {
6651+
const ppl = firestore.pipeline().collection(COLLECTION_NAME).search({
6652+
query: 'chicken',
6653+
limit: 2,
6654+
offset: 2,
6655+
// queryEnhancement: 'disabled'
6656+
});
6657+
6658+
const snapshot = await ppl.execute();
6659+
expectResults(snapshot, 'goldenWaffle');
6660+
});
6661+
});
66266662
// });
66276663
});
66286664

handwritten/firestore/dev/test/pipelines/stage.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,11 @@ describe('stage option serialization', () => {
257257
.database()
258258
.search({
259259
query: 'foo',
260-
// limit: 1,
261-
// retrievalDepth: 2,
262-
// offset: 3,
260+
limit: 1,
261+
retrievalDepth: 2,
262+
offset: 3,
263263
// queryEnhancement: 'required',
264-
// languageCode: 'en-US',
264+
languageCode: 'en-US',
265265
sort: [field('foo').ascending()],
266266
addFields: [constant(true).as('bar')],
267267
// select: [field('id')],
@@ -281,15 +281,15 @@ describe('stage option serialization', () => {
281281
foo: {
282282
stringValue: 'bar1',
283283
},
284-
// language_code: {
285-
// stringValue: 'en-US',
286-
// },
287-
// limit: {
288-
// integerValue: '1',
289-
// },
290-
// offset: {
291-
// integerValue: '3',
292-
// },
284+
language_code: {
285+
stringValue: 'en-US',
286+
},
287+
limit: {
288+
integerValue: '1',
289+
},
290+
offset: {
291+
integerValue: '3',
292+
},
293293
query: {
294294
functionValue: {
295295
args: [
@@ -303,9 +303,9 @@ describe('stage option serialization', () => {
303303
// query_enhancement: {
304304
// stringValue: 'required',
305305
// },
306-
// retrieval_depth: {
307-
// integerValue: '2',
308-
// },
306+
retrieval_depth: {
307+
integerValue: '2',
308+
},
309309
// select: {
310310
// mapValue: {
311311
// fields: {

0 commit comments

Comments
 (0)