Created
April 25, 2026 12:37
-
-
Save erikhatcher/c93355541225350066ec2f6b8ab118b3 to your computer and use it in GitHub Desktop.
Search Views
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // mongosh $MONGODB_URI run_demos.js | |
| array_size_demo = { | |
| description: "Enriching the index with the size of an array.", | |
| docs: [ | |
| { | |
| _id: 1, | |
| values: [1,2,3,4] | |
| }, | |
| { | |
| _id: 2, | |
| values: [1,2,3,4,5] | |
| } | |
| ], | |
| view_pipeline: [ | |
| { | |
| $addFields: { | |
| num_values: { $size: "$values" } | |
| } | |
| } | |
| ], | |
| search_pipeline: [ | |
| { | |
| $search: { | |
| index: "view_index", | |
| equals: { | |
| path: "num_values", | |
| value: 4 | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| partial_demo = { | |
| description: "Indexing only non-archived documents.", | |
| docs: [ | |
| { | |
| _id: 1, | |
| }, | |
| { | |
| _id: 2, | |
| archived: true | |
| } | |
| ], | |
| view_pipeline: [ | |
| { | |
| $match: { | |
| $expr: { | |
| $ne: ["$archived", true] | |
| } | |
| } | |
| } | |
| ], | |
| search_pipeline: [ | |
| { | |
| $search: { | |
| index: "view_index", | |
| exists: { | |
| path: "_id" | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| unsearchable_demo = { | |
| description: "Making a field unsearchable.", | |
| docs: [ | |
| { | |
| _id: 1, | |
| public: "this is public info", | |
| private: "this is private info" | |
| } | |
| ], | |
| view_pipeline: [ | |
| { | |
| $set: { | |
| private: "$$REMOVE" | |
| } | |
| } | |
| ], | |
| search_pipeline: [ | |
| { | |
| $search: { | |
| index: "view_index", | |
| text: { | |
| query: "private", | |
| path: { wildcard: "*" }, | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| // flatten_attributes_demo = { | |
| // description: "Flattening an array of key-value pairs to make them searchable.", | |
| // docs: [ | |
| // { | |
| // _id: 1, | |
| // extras: [ | |
| // { key: "color", value: "red" }, | |
| // { key: "shape", value: "square" } | |
| // ] | |
| // } | |
| // ], | |
| // view_pipeline: [ | |
| // { | |
| // $addFields: { | |
| // extras: { | |
| // $arrayToObject: { | |
| // $map: { | |
| // input: "$extras", | |
| // as: "item", | |
| // in: [ "$$item.key", "$$item.value" ] | |
| // } | |
| // } | |
| // } | |
| // } | |
| // } | |
| // ], | |
| // search_pipeline: [ | |
| // { | |
| // $search: { | |
| // index: "view_index", | |
| // text: { | |
| // query: "red", | |
| // path: "extras.color" | |
| // } | |
| // } | |
| // } | |
| // ] | |
| // } | |
| // ... $arrayToObject: { | |
| // ... $map: { | |
| // ... input: "$extras", | |
| // ... as: "item", | |
| // ... in: [ "$$item.key", "$$item.value" ] | |
| // ... } | |
| // ... } | |
| // ... } | |
| // ... } | |
| // ... } | |
| // ... ] | |
| demos = { | |
| 'array_size': array_size_demo, | |
| 'partial': partial_demo, | |
| 'unsearchable': unsearchable_demo, | |
| // 'flatten_attributes': flatten_attributes_demo | |
| } | |
| function run_demo(demo_name) { | |
| demo = demos[demo_name]; | |
| db = db.getSiblingDB('view_demo_' + demo_name); | |
| console.log('\nCreating fresh environment...'); | |
| db.view.dropSearchIndex('view_index'); | |
| db.view.drop(); | |
| db.docs.deleteMany({}); | |
| console.log(' - environment ready'); | |
| console.log('\nInserting some docs:'); | |
| result = db.docs.insertMany(demo.docs); | |
| console.log(db.docs.find({}).toArray()); | |
| if (demo_name == 'array_size') { | |
| // only this demo shows winning plan | |
| match_stage = { $match: { values: { $size: 4 } } } | |
| result = db.docs.aggregate([match_stage]).explain(); | |
| // `winningPlan` is COLLSCAN | |
| console.log(JSON.stringify(match_stage) + " winningPlan: " +result["queryPlanner"]["winningPlan"]["stage"]); | |
| } | |
| console.log('\nCreating enrichment view...') | |
| view_pipeline = demo.view_pipeline | |
| db.createView( | |
| "view", | |
| "docs", | |
| view_pipeline | |
| ) | |
| console.log('View created: ') | |
| console.log(view_pipeline) | |
| console.log('\nDocs from view:') | |
| console.log(db.view.find({}).toArray()); | |
| db.view.createSearchIndex( | |
| "view_index", | |
| { | |
| "mappings": { | |
| "dynamic": true | |
| } | |
| } | |
| ) | |
| console.log('\nSearch index created. Polling until READY...') | |
| index_status = "TBD" | |
| while (index_status != "READY") { | |
| sleep(3000) | |
| indexes = db.view.getSearchIndexes({name: "view_index"}) | |
| index_status = indexes[0]["status"] | |
| } | |
| console.log('Index is READY') | |
| search_pipeline = demo.search_pipeline | |
| console.log('\nSearch pipeline:') | |
| console.log(search_pipeline) | |
| console.log('\nSearch results:') | |
| results = db.view.aggregate(search_pipeline).toArray(); | |
| console.log(results); | |
| } | |
| demo_names = ['array_size', 'partial', 'unsearchable'] | |
| for (demo_name of demo_names) { | |
| console.log('\n\n==============================='); | |
| console.log('Demo: ' + demo_name); | |
| console.log(demos[demo_name].description); | |
| console.log('===============================\n'); | |
| run_demo(demo_name); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment