summaryrefslogtreecommitdiff
path: root/jstests/aggregation/sources/lookup/lookup_contains_text.js
blob: 0ecbb60d68335bb690ac88fc2c51bb19212ff094 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Tests that given a $text stage before a $lookup stage, the $lookup's subpipeline cannot
// reference the text score metadata from that $text search.
// TODO: Reenable test on passthroughs with sharded collections as part of SERVER-38996.
// @tags: [assumes_unsharded_collection]
(function() {
"use strict";

load("jstests/aggregation/extras/utils.js");  // For "assertErrorCode".

const outer = db.outer;
const inner = db.inner;

outer.drop();
inner.drop();

const kNoTextScoreAvailableErrCode = 40218;

// This pipeline is never legal, because the subpipeline projects out a textScore but does not
// begin with a $text search.
let pipeline = [
    {$match: {$text: {$search: "foo"}}},
    {$lookup: {from: "inner", as: "as", pipeline: [{$project: {score: {$meta: "textScore"}}}]}}
];

assert.commandWorked(outer.insert({_id: 100, a: "foo"}));
assert.commandWorked(inner.insert({_id: 100, a: "bar apple banana"}));

// Neither 'outer' nor 'inner' have  text indexes.
assertErrorCode(outer, pipeline, ErrorCodes.IndexNotFound);

// Only 'outer' has a text index.
assert.commandWorked(outer.createIndex({a: "text"}, {name: "outer_first_index"}));
assertErrorCode(outer, pipeline, kNoTextScoreAvailableErrCode);

// Only 'inner' has a text index.
assert.commandWorked(outer.dropIndex("outer_first_index"));
assert.commandWorked(inner.createIndex({a: "text"}));
assertErrorCode(outer, pipeline, ErrorCodes.IndexNotFound);

// Both 'outer' and 'inner' have a text index.
assert.commandWorked(outer.createIndex({a: "text"}));
assertErrorCode(outer, pipeline, kNoTextScoreAvailableErrCode);

// A pipeline with two text searches, one within a $lookup, will work.
pipeline = [
        {$match: {$text: {$search: "foo"}}},
        {
          $lookup: {
              from: "inner",
              as: "as",
              pipeline: [
                  {$match: {$text: {$search: "bar apple banana hello"}}},
                  {$project: {score: {$meta: "textScore"}}}
              ]
          }
        }
    ];

let expected = [{"_id": 100, "a": "foo", "as": [{"_id": 100, "score": 2}]}];
assert.eq(outer.aggregate(pipeline).toArray(), expected);

// A lookup with a text search in the subpipeline will correctly perform that search on 'from'.
pipeline = [{
        $lookup: {
            from: "inner",
            as: "as",
            pipeline: [{$match: {$text: {$search: "bar apple banana hello"}}}]
        }
    }];
expected = [{"_id": 100, "a": "foo", "as": [{"_id": 100, "a": "bar apple banana"}]}];

assert.eq(outer.aggregate(pipeline).toArray(), expected);

// A lookup with two text searches and two text score $projects will have the text scores
// reference the relevant text search.
pipeline = [
        {$match: {$text: {$search: "foo"}}},
        {
          $lookup: {
              from: "inner",
              as: "as",
              pipeline: [
                  {$match: {$text: {$search: "bar apple banana hello"}}},
                  {$project: {score: {$meta: "textScore"}}}
              ]
          }
        },
        {$project: {score: {$meta: "textScore"}, as: 1}},
    ];

expected = [{"_id": 100, "as": [{"_id": 100, "score": 2}], "score": 1.1}];

assert.eq(outer.aggregate(pipeline).toArray(), expected);

// Given a $text stage in the 'from' pipeline, the outer pipeline will not be able to access
// this $text stage's text score.
pipeline = [
        {
          $lookup: {
              from: "inner",
              as: "as",
              pipeline: [{$match: {$text: {$search: "bar apple banana hello"}}}]
          }
        },
        {$project: {score: {$meta: "textScore"}, as: 1}},
    ];

assertErrorCode(outer, pipeline, kNoTextScoreAvailableErrCode);
}());