MongoDB shell: printing to console without a trailing newline? - javascript

Is there a way to write to STDOUT without a trailing newline from the Mongo shell? I can't seem to find anything other than print() available.

This is related to my SO question on reading a line from the console. Per #Stennie's comment, it is not possible in the current (2.0.6) version of the Mongo shell.

There might be ways to work around it. You can accumulate the results in an intermediate variable (could be an array, string or any other data structure), then print the entire thing in a single line. Below example illustrates use of an array to capture values from query results, then array is converted to string with comma as a separator. In my case I'm interested in just the _id field:
var cursor = db.getCollection('<collection name>').find(<your query goes here>)
let values = []
cursor.forEach((doc) => values.push(doc._id))
print(values.join(','))
Depending on how many results you're expecting, not sure if space consumed by the intermediate data structure might overwhelm memory. If that's the case can craft the query to return smaller, subsets of data that when added together comprise the full result set you're going for.

This is quite old question, however still relevant, so answering.
One can use printjsononeline().

Related

Manually "compressing" a very large number of boolean values in JSON

We have a data model where each entity has 600 boolean values. All of this data needs to travel over the wire from a node.js backend to an Angular frontend, via JSON.
I was thinking about various ways to optimize it (this is an internal API and is not public, so adherence to best practices is less important than performance and saving bandwidth).
I am not a native Javascript speaker, so was hoping to get some feedback on some of the options I was considering, which are:
Turning it into a bitfield and using a huge (600-bit) BigInt.
Is this a feasible approach? I can imagine it would probably be pretty horrific in terms of performance
Splitting the 600 bits into 10 integers (since JS integers are 64 bit), and putting those into an array in the JSON
Base64 encoding a binary blob (will be decoded to a UInt8Array I'm assuming?)
Using something like Protobuf? It might be overkill because I don't want more than 1-2 hours spent on this optimization; definitely don't want to make major changes to the architecture either
Side note: We don't have compression on the server end due to infrastructure reasons, which makes this more complicated and is the reason for us implementing this on the data level.
Thanks!
as Evan points out, transforming your boolean for example into a single character for true="t" and false="f", the 600 boolean will become a joined string of 600 chars which can very well be split into 3 strings of 200 of the sizes, then once received on the front just concatenate the transit and if you want to recover your Bollean values ​​from the string, with a simple reg it becomes possible.
I don't know how the data is set and then obtained, just changing this parameter to which I think needs to be automated.
Once the final string is obtained on the front here is an example of reg ex which can convert your string to an array with your 600 boolean. It is also possible to define indexes by defining an object instead of the array.
function convert_myBool(str)
{
/*var reg = new RegExp('.{1}', 'g');
var tmpTab = str.replace(reg, function(matched){
return matched == "t"?true:false;
});*/
//map is best
tmpTab = str.split('').map((value) =>{
return value == "t"?true:false;
});
return tmpTab;
};
I wrote this dynamically so of course it can be pondered, improved replaced etc. Hoping to have helped :)
Can it be sorted in any way? If there are boolean values that always occur in conjunction with a related value you may be able to group them and simplify.
Depending on what your use for that data is, you may be able to cache some of the it or memoize based on usage frequency. There would be a space tradeoff with caching, however.

Best way to concatenate multiple strings?

I have a project, where user can put in drop-down values that can be selected. One can select multiple values at a time. So, we have to store the selection and get it on edit mode.
First thought
Let's store them as comma separated in DB.
f.e.
If suggestions are A , B , C and user selects A and B, I was going to store A,B in DB and while getting back the value split it with comma.
Problem arises when user has genuine "comma" in the field, for an instance first,option & second,option. At that time joining with comma won't work.
Second thought
I can think of another option to store it in a stringified array format and parse it while getting back.
For the above instance, it would store the data as ["first,option","second,option"]. It seems to be a good (and only) option for me.
Even though I have a bit of hesitation doing so (which lead me questioning here!) because my users can access the api/DB value directly and for them it doesn't look good.
So, Is there any other way to address this issue to benefit both parties, developers and users? Thanks in advance!!
I'd suggest using a standardized format such as JSON, XML etc.
Serialize and parse and with a widely used library so all escaping of reserved / special characters is done for you. Rolling your own here will cause you problems!
Better yet, use different fields for each suggestion, this is a better design in general. As long as the number of potential fields is finite this will work, e.g. 1-10 suggestions.
If you're going down the JSON route, we can do this in JavaScript like this:
let suggestions = ['Choice A, commas are not, a problem, though punctuation is.', 'Choice B', 'Choice C'];
let json = JSON.stringify(suggestions);
// Save to DB
saveToDB(json);
let jsonFromDB = loadFromDB();
let deserializedSuggestions = JSON.parse(jsonFromDB);
console.log(deserializedSuggestions);
we use semicolon (;) for this exact use case in our current project.
So, as per your question, they will be stored in the DB as option1;option2;option3
and when we get it back from the DB we can use the split() method on it to convert it into an array of substrings.
var str = "option1;option2;option3";
var res = str.split(";");
console.log(res);
which would result in (3) ["option1", "option2", "option3"] in the console.
hope this helps.

Parse.com relations count

I want to query object from Parse DB through javascript, that has only 1 of some specific relation object. How can this criteria be achieved?
So I tried something like this, the equalTo() acts as a "contains" and it's not what I'm looking for, my code so far, which doesn't work:
var query = new Parse.Query("Item");
query.equalTo("relatedItems", someItem);
query.lessThan("relatedItems", 2);
It seems Parse do not provide a easy way to do this.
Without any other fields, if you know all the items then you could do the following:
var innerQuery = new Parse.Query('Item');
innerQuery.containedIn('relatedItems', [all items except someItem]);
var query = new Parse.Query('Item');
query.equalTo('relatedItems', someItem);
query.doesNotMatchKeyInQuery('objectId', 'objectId', innerQuery);
...
Otherwise, you might need to get all records and do filtering.
Update
Because of the data type relation, there are no ways to include the relation content into the results, you need to do another query to get the relation content.
The workaround might add a itemCount column and keep it updated whenever the item relation is modified and do:
query.equalTo('relatedItems', someItem);
query.equalTo('itemCount', 1);
There are a couple of ways you could do this.
I'm working on a project now where I have cells composed of users.
I currently have an afterSave trigger that does this:
const count = await cell.relation("members").query().count();
cell.put("memberCount",count);
This works pretty well.
There are other ways that I've considered in theory, but I've not used
them yet.
The right way would be to hack the ability to use select with dot
notation to grab a virtual field called relatedItems.length in the
query, but that would probably only work for me because I use PostGres
... mongo seems to be extremely limited in its ability to do this sort
of thing, which is why I would never make a database out of blobs of
json in the first place.
You could do a similar thing with an afterFind trigger. I'm experimenting with that now. I'm not sure if it will confuse
parse to get an attribute back which does not exist in its schema, but
I'll find out, by the end of today. I have found that if I jam an artificial attribute into the objects in the trigger, they are returned
along with the other data. What I'm not sure about is whether Parse will decide that the object is dirty, or, worse, decide that I'm creating a new attribute and store it to the database ... which could be filtered out with a beforeSave trigger, but not until after the data had all been sent to the cloud.
There is also a place where i had to do several queries from several
tables, and would have ended up with a lot of redundant data. So I wrote a cloud function which did the queries, and then returned a couple of lists of objects, and a few lists of objectId strings which
served as indexes. This worked pretty well for me. And tracking the
last load time and sending it back when I needed up update my data allowed me to limit myself to objects which had changed since my last query.

Storing arrays in localstorage

I'm building an app with Appery.io. It's basically a search app that returns results and then you can click into the results to see details.
Results are returned from a REST api in JSON format, and each results has a number of different items in it, including one that is a JSON array which contains multiple sets of three name/value pairs.
I need the array associated with each result to be available in the details page for that result. I don't want to simply run the search again in the details page, because it is a relatively lengthy process and would slow down the entire app.
I'm aware of using JSON.stringify() to make the array a string, and then storing each array in local storage. However, when I do that in Appery.io, it seems that I either a) just save the first result of the array, or b) am doing it wrong.
Can any provide any insight into how I can go about doing this? Happy to provide code, clarify my question, etc.
Thanks!
If there's some problem using JSON.stringify() with Appery.io, try the approach storing them as comma-separated string (unless you're having commas in values):
> ["foo", "bar"].join();
>> "foo,bar"
And them returning them:
> "foo,bar".split(",");
>> ["foo, "bar"]
Of course, if you're having commas in values, you can use explicitly specified separator for values, like:
> ["foo,bar", "foz,baz"].join("#");
>> "foo,bar#foz,baz"

Lucene-like searching through JSON objects in JavaScript

I have a pretty big array of JSON objects (its a music library with properties like artist, album etc, feeding a jqgrid with loadonce=true) and I want to implement lucene-like (google-like) query through whole set - but locally, i.e. in the browser, without communication with web server. Are there any javascript frameworks that will help me?
Go through your records, to create a one time index by combining all search
able fields in a single string field called index.
Store these indexed records in an Array.
Partition the Array on index .. like all a's in one array and so on.
Use the javascript function indexOf() against the index to match the query entered by the user and find records from the partitioned Array.
That was the easy part but, it will support all simple queries in a very efficient manner because the index does not have to be re-created for every query and indexOf operation is very efficient. I have used it for searching up to 2000 records. I used a pre-sorted Array. Actually, that's how Gmail and yahoo mail work. They store your contacts on browser in a pre-sorted array with an index that allows you to see the contact names as you type.
This also gives you a base to build on. Now you can write an advanced query parsing logic on top of it. For example, to support a few simple conditional keywords like - AND OR NOT, will take about 20-30 lines of custom JavaScript code. Or you can find a JS library that will do the parsing for you the way Lucene does.
For a reference implementation of above logic, take a look at how ZmContactList.js sorts and searches the contacts for autocomplete.
You might want to check FullProof, it does exactly that:
https://github.com/reyesr/fullproof
Have you tried CouchDB?
Edit:
How about something along these lines (also see http://jsfiddle.net/7tV3A/1/):
var filtered_collection = [];
var query = 'foo';
$.each(collection, function(i,e){
$.each(e, function(ii, el){
if (el == query) {
filtered_collection.push(e);
}
});
});
The (el == query) part of course could/should be modified to allow more flexible search patterns than exact match.

Categories