cat file.sh | mongo … is UUOC, <file.sh mongo … is better.
Side note: why .sh? It doesn't matter to mongo or whatever, but people will expect file.sh to be a shell script. From now on I'm using file1 instead.
man 1 mongo gives an example: mongo script1.js script2.js script3.js, so I expect mongo … file1 to work as well.
#!/path/to/mongo or #!/usr/bin/env mongo can be used as a shebang. Use the shebang in file1, make the file executable (chmod +x file1) and run it directly (e.g. by typing ./file1 in its directory). Place file1 in a directory specified in your PATH and you will be able to run it by simply calling file1.
Note a shebang specifies an interpreter and at most one additional argument. Technically you can add one argument (like your <EXPECTED_COLLECTION>) after #!/path/to/mongo (but not after #!/usr/bin/env mongo where mongo is the argument), but I would rather do everything in JavaScript below the shebang.
you can specify the mongodb connection parameters inside of the javascript file using the Mongo() constructor.
(source)
psql is somewhat different. A basic way to interpret a script is psql -f file2 (psql <file2 should also work, but see what man 1 psql says about it where it describes -f).
A shebang like #!/path/to/psql -f would work, if psql ignored lines starting with # (like e.g. sh does) or if it at least recognized #!… in the first line as a shebang and skipped the line. It doesn't. There are few tricks to circumvent this; see Shebang for psql.
One of the answers from the last link uses a here document in a shell script. This approach is quite powerful. An example of a Python script inside a Bash script is here: How to include python script inside a bash script? Similarly you can pass an embedded script to mongo … (or to psql -f -):
#!/bin/sh
mongo … << 'EOF'
db.EXPECTED_COLLECTION.remove("_id":1234)
EOF
If you call this script file.sh then the .sh part will not be misleading. It is a shell script.
Note << EOF instead of << 'EOF' will allow you to pass expanded variables from the shell to mongo.