Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Editing a line in multiple lines in Mongo shell

Tags:

shell

mongodb

After pasting in a block spanning multiple lines, by default it seems you can only edit the last line. What would be the shortcuts for editing the other lines (preceded by '...')?

like image 521
David Rosson Avatar asked Jan 17 '15 14:01

David Rosson


4 Answers

A different approach would be to not paste multi-line blocks into the shell directly. Instead, you can use the edit helper.

In the .mongorc.js file found in your home directory, you can define what editor you would like to use:

EDITOR="vim"

Then while in the shell you can issue the edit command

edit foo

This will present you with an empty page where you can set foo to be a query document

{ name: "bar" }

a function

function foo() {
  print("BAR!");
}

or probably most usefully an aggregate query

[
  {
    $match: {
      name: "bar"
    }
  },
  {
    $group: {
      _id: null,
      ageSum: {
        $sum: "$age"
      }
    }
  },
  {
    $project: {
      _id: 0,
      n: "$name",
      a: "ageSum"
    }
  }
]

db.test.aggregate(foo)

like image 80
NoOutlet Avatar answered Nov 15 '22 11:11

NoOutlet


For those wondering why typing edit on the shell does not work, that's because you need to include a value for the edit, like this:

edit <something>

It can be anything, like this edit input, enter the document's content into the editor's document, save and use like this db.collection.insert(input) (assuming the name was input

otherwise you'll get

ReferenceError: edit is not defined :
like image 30
Ivan Alonso Avatar answered Nov 15 '22 12:11

Ivan Alonso


when you paste multi-line command in mongoshell, when you press enter button you see {...}

Causes :

  1. When command is not properly open-close.

solution :

  1. first come out from terminal by pressing enter/return button twice in keyboard.
  2. correct your command and re-paste it.
like image 30
Shamanth Ramesh Avatar answered Nov 15 '22 10:11

Shamanth Ramesh


If you're in the usual mode sorry, you can't paste in multiple lines and then have a way to edit a line in the middle before execution. It's the limitation of using a line editor in an interpreter- as soon as you hit the return the command line interpretation will be triggered.

In the bash shell you can use edit-and-execute-command command (bound to [Ctrl-x, Ctrl-e] by default) to give you a normal file editor to freely work in without triggering command execution every time you end a line.

As NoOutlet has pointed out the mongo shell can do something very similar with the edit var_name shell command. If you know the [Ctrl-x, Ctrl-e] trick with the bash shell and want to learn the differences when using edit var_name mode please read on.

The first difference I note is that there is no control-key binding- you can only start it by typing edit var_name at the beginning of a new prompt.

As you might know in the bash case it tries to find and open an editor program that is named in the $VISUAL or $EDITOR environment variables, or uses "emacs" as fall-through. The mongo shell will look only for an EDITOR var, but it does so in two places- first from the javascript scope, then in the regular process environment variable. Using "vim" as an example just execute "var EDITOR = 'vim';" in the mongo shell's javascript interpreter to set it there, or execute "export EDITOR=vim" in your unix shell (or .bashrc etc.) before opening the mongo shell.

The next difference is that when you save and quit out from your editor it goes back to the regular mongo shell processing and executes "var_name = <the code in you finished in your editor>". So it can be a var, it can be a function, it can be a statement, it can be multiple statements, but it can't be incomplete. It is assumed you wanted to only give a complete piece of code, unlike the usual mongo command line interpreter that waits until you A) either finish your code by having a closed piece of syntax (e.g. no unclosed brackets) or B) enter two empty lines to indicate you want to abandon the command you started writing.

You don't have to assign anything important into the var you named when you began the editor. It can be a useful idiom to do so, but the implementation doesn't require it. You can do any regular database command, set vars, function objects, etc. etc. To give a walkthrough open a mongo shell, set EDITOR if it's not already set, then start your external editor by typing "edit foo" and hit enter, then insert and save the following code sample in the external editor session (where you use vim/emacs/nano etc.)

999; //this is the only thing that will be evaluated into "foo"

db.new_test.insert({"junk": 1});

var colNames = db.getCollectionNames();

function mongoSystemColFilter(x) {
  return x.substring(0,7) == "system.";
}

After that is saved and you exit, that code will be executed in the javascript interpreter in the same scope as your prompt. Back in the usual mode you can see that foo was just set to just the result of the first statement, and all the other objects that were created (javascript vars, functions, and db objects) are still available in scope.

> print(foo);
999
> for (i in colNames) { 
...   var cnm = colNames[i];  
...   if (mongoSystemColFilter(cnm)) { 
...     print("Ignoring [" + cnm + "] because it is a system collection");
...   } else {
...     print("Okay, found our [" + cnm + "] collection");
...   }
... }
Okay, found our [new_test] collection
Ignoring [system.indexes] because it is a system collection
> db.new_test.drop()
true
like image 5
Akira Kurogane Avatar answered Nov 15 '22 12:11

Akira Kurogane