Meteor: how do I return data from fields in a specific object? - json

This should be a fairly simple one.
myobject has various properties, _id, name, createdBy, date etc
In my find query I want to only return specific fields from within myObject. So for example, what would I need to do to modify the find query below so that only name was returned?
myCollection.find({createdBy: someId}, {fields: {myObject: 1}}).fetch();
Currently this will return everything in myObject which it should do, I just want one field within myObject returned.

Here is a way to do it within the query:
myCollection.find({createdBy: someId}, {fields: {'myObject.name':
1}}).fetch();
Note the quotes around
'myObject.name'

Lets assume we are talking about posts, and a post document looks like this:
{
_id: 'abc123',
title: 'All about meteor',
author: {
firstName: 'David',
lastName: 'Weldon'
}
}
You can then extract all of the last names from all of the authors with this:
var lastNames = Posts.find().map(function(post) {
return post.author.lastName;
});
Modify the selector and options as needed for your collection. Using fields in this case may be a small optimization if you are running this on the server and fetching the data directly from the DB.

Related

How can I pass parameters to getter in Sequelize model?

What I'm doing:
I'm reading csv which contains data like townships, religions and so on. In the csv, they are text values. But of course in my table in the database, they are foreign_key. So to insert those, I need to map those text values to id.
It is possible to get the id like below.
const { townshipId } = await models.Township.findOne({
where: { name: township },
attributes: ["townshipId"],
raw: true,
});
The problem:
But the problem what I think is that those findOne(s) will be populated in my entire method because I have like 50 other properties besides township.
What I'm trying
I'm trying to pass township-name to a getter method, expecting its equivalent townshipId.
I found out that it is possible to use getter and setter in sequelize. But I don't find how to pass parameters to those.
My question
Am I trying the correct way to import the csv data? How can I use getters (and setters) with parameters in sequelize?
Maybe if you want to exclude columns from the result, you pass the "attributes" field like:
attributes: { exclude: ['field1','field2'] }
This way you wont show the columns "field1" and "field2" in the result.

Firebase Database Search Query

I am trying to search my database using a string, such as "A". I was just watching this Firebase tutorial Common SQL Queries converted for the Firebase Database - The Firebase Database For SQL Developers #4 and it explains that, in order to search the database for a string (in a certain location), you must use:
firebase.database().ref.child("child_name_here")
.queryOrdered(byChild: "child_name_here")
.queryStarting(atValue: "value_here_uppercase")
.queryEnding(atValue: "value_here_uppercase\\uf8ff")
You must use two \\ in the ending value as an escape character in order to get one \.
When I try this with my Firebase database, it does not work. Here is my database:
{
"Schools": {
"randomUID": {
"location" : "anyTown, anyState",
"name" : "anyName"
}
}
}
Here is my query:
databaseReference.child("Schools")
.queryOrdered(byChild: "name")
.queryStarting(atValue: "A")
.queryEnding(atValue: "A\\uf8ff") ...
When I go to print the snapshot from Firebase, I get back.
If I get rid of the ending .queryEnding(atValue: "A\\uf8ff"), the database returns all of the schools in the Schools node.
How can I search the Firebase database using a String?
queryStarting() and queryEnding() can be used for number. For example: you can get objects with someField varying from 3 to 10.
for searching string: you can search whole string using queryEqualToValue().
This shows all customers that match Wick. (It's not swift but may give you an idea)
// sample
let query = 'Wick'
clientsRef.orderByChild('name')
.startAt(query)
.endAt(query + '\uf8ff')
.once('value', (snapshot) => {
....
})

CSV Parser through angularJS

I am building a CSV file parser through node and Angular . so basically a user upload a csv file , on my server side which is node the csv file is traversed and parsed using node-csv
. This works fine and it returns me an array of object based on csv file given as input , Now on angular end I need to display two table one is csv file data itself and another is cross tabulation analysis. I am facing problem while rendering data, so for a table like
I am getting parse responce as
For cross tabulation we need data in a tabular form as
I have a object array which I need to manipulate in best possible way so as to make easily render on html page . I am not getting a way how to do calculation on data I get so as to store cross tabulation result .Any idea on how should I approach .
data json is :
[{"Sample #":"1","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"2","Gender":"Male","Handedness;":"Left-handed;"},{"Sample #":"3","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"4","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":"5","Gender":"Male","Handedness;":"Left-handed;"},{"Sample #":"6","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":"7","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"8","Gender":"Female","Handedness;":"Left-handed;"},{"Sample #":"9","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":";"}
There are many ways you can do this and since you have not been very specific on the usage, I will go with the simplest one.
Assuming you have an object structure such as this:
[
{gender: 'female', handdness: 'lefthanded', id: 1},
{gender: 'male', handdness: 'lefthanded', id: 2},
{gender: 'female', handdness: 'righthanded', id: 3},
{gender: 'female', handdness: 'lefthanded', id: 4},
{gender: 'female', handdness: 'righthanded', id: 5}
]
and in your controller you have exposed this with something like:
$scope.members = [the above array of objects];
and you want to display the total of female members of this object, you could filter this in your html
{{(members | filter:{gender:'female'}).length}}
Now, if you are going to make this a table it will obviously make some ugly and unreadable html so especially if you are going to repeat using this, it would be a good case for making a directive and repeat it anywhere, with the prerequisite of providing a scope object named tabData (or whatever you wish) in your parent scope
.directive('tabbed', function () {
return {
restrict: 'E',
template: '<table><tr><td>{{(tabData | filter:{gender:"female"}).length}}</td></tr><td>{{(tabData | filter:{handedness:"lefthanded"}).length}}</td></table>'
}
});
You would use this in your html like so:
<tabbed></tabbed>
And there are ofcourse many ways to improve this as you wish.
This is more of a general data structure/JS question than Angular related.
Functional helpers from Lo-dash come in very handy here:
_(data) // Create a chainable object from the data to execute functions with
.groupBy('Gender') // Group the data by its `Gender` attribute
// map these groups, using `mapValues` so the named `Gender` keys persist
.mapValues(function(gender) {
// Create named count objects for all handednesses
var counts = _.countBy(gender, 'Handedness');
// Calculate the total of all handednesses by summing
// all the values of this named object
counts.Total = _(counts)
.values()
.reduce(function(sum, num) { return sum + num });
// Return this named count object -- this is what each gender will map to
return counts;
}).value(); // get the value of the chain
No need to worry about for-loops or anything of the sort, and this code also works without any changes for more than two genders (even for more than two handednesses - think of the aliens and the ambidextrous). If you aren't sure exactly what's happening, it should be easy enough to pick apart the single steps and their result values of this code example.
Calculating the total row for all genders will work in a similar manner.

Iterating through couchbase keys without a view

In couchbase, I was wondering if there was a way - WITHOUT using a view - to iterate through database keys. The admin interface appears to do this, but maybe its doing something special. What I'd like to is make a call like this to retrieve an array of keys:
$result = $cb->get("KEY_ALBERT", "KEY_FRED");
having the result be an array [KEY_ALEX, KEY_BOB, KEY_DOGBERT]
Again, I don't want to use a view unless there's no alternative. Doesn't look like its possible, but since the "view documents" in the admin appears to do this, I thought i'd double-check. I'm using the php interface if that matters.
Based on your comments, the only way is to create a simple view that emit only the id as par of the key:
function(doc, meta) {
emit( meta.id );
}
With this view you will be able to create query with the various options you need :
- pagination, range, ...
Note: you talk about the Administration Console, the console use an "internal view" that is similar to what I have written above (but not optimized)
I don't know about how couchbase admin works, but there are two options. First option is to store your docs as linked list, one doc have property (key) that points to another doc.
docs = [
{
id: "doc_C",
data: "somedata",
prev: "doc_B",
next: "doc_D"
},
{
id: "doc_D",
data: "somedata",
prev: "doc_C",
next: "doc_E"
}
]
The second approach is to use sequential id. You should have one doc that contain sequence and increment it on each add. It would be something like this:
docs = [
{
id: "doc_1",
data: "somedata"
},
{
id: "doc_2",
data: "somedata"
}
...
]
In this way you can do "range requests". To do this you form array of keys on server side:
[doc_1, doc_2 .... doc_N]and execute multiget query. Here is also a link to another example
The couchbase PHP sdk does support multiget requests. For a list of keys it will return an array of documents.
getMulti(array $ids, array $cas, int $flags) : array
http://www.couchbase.com/autodocs/couchbase-php-client-1.1.5/classes/Couchbase.html#method_getMulti

Recursive as_array for One-to-many relationships with Kohana 3 ORM

To begin with I'd like to say I know how to create ugly solutions for my problem. I am searching good solutions and best practices :)
How do I create deep hierarchial arrays (to json_encode later) from Kohana 3 ORM objects including related objects where the relation type is one-to-many?
The problem is that the ORM->as_array() method does work recursively for the "has one" and "belongs to" relationships but will stop and force you to use ->find_all() manually when you encounter a "has many" relationship.
Say I am creating a JSON API REST server using Kohana 3 and the built in ORM.
When someone looks at this URL: www.example.com/api/user?id=5
They will be served a JSON object for the user where id=5.
These are the orm-models and the relations:
User belongs to a Country
User has many Messages.
Message belongs to a Category
I would like this to work:
echo json_encode(
ORM::factory('user', 5)
->with('country')
->with('messages')
->with('messages:category')
->find()
->as_array()
);
and give me output like this:
{
name: "John"
age: 54,
country_id: 5,
country: {
name: 'Sweden',
code: 'SE'
},
messages: {
{
content: 'Lorem ipsum dolor...',
category_id: 1,
category: {...}
},
{
content: 'Sit amet elit...',
category_id: 2,
category: {...}
},
{
content: 'Consectetur ipsum dolor...',
category_id: 3,
category: {...}
}
}
}
BUT THAT WONT WORK.
This is all you would get:
{
name: "John"
age: 54,
country_id: 5,
country: {
name: 'Sweden',
code: 'SE'
}
}
Has someone forked or extended the Kohana 3 ORM to support this kind functionality?
Does someone know of any good Kohana 3 api module that takes care of this issue for you somehow?
As far as I know, there is no way to do this using only the ORM. This is the case for two reasons:
If a message has a relation for category, that usually means that category has a corresponding relation for the messages in the category. If you want to get the message "in full" - i.e. including its category - let's say that you also want to get the category "in full" - i.e. including its messages. This is obviously a very bad idea, as you could very easily design yourself into an infinite loop. In other words, if there was a magic "recurse all relations" capability, how would it know when to stop recursing?
All that the ORM is doing behind the scenes when you call find() is building a SQL query that returns a row of data from the database. However, what you are trying to do is too complicated for a single query that returns a single row. (There is a way to retrieve multiple rows as one row with comma-separated values in each field using MySQL's GROUP_CONCAT function, but I guarantee you that it is not worth the trouble.)
For both of these reasons, the ORM's with() method only works on belongs_to (in your case, the user's country and the message's category).
One way to do this query is to break it up into three steps, like this:
// Step 1: Get the user
$user = ORM::factory('user', 5)
->with('country')
->find();
// Step 2: Get the messages
$user->messages
->with('category')
->find_all();
// Step 3: Make user and the messages into arrays.
// User is easy, but messages are a little harder
// because they need to turn
// from "an object containing an array of objects"
// into "an array of arrays."
$user_arr = $user->as_array();
$fixer = function($obj)
{
return $obj->as_array();
};
$user_arr['messages'] = array_map($fixer, $user->messages->as_array());
// Now you can output it
echo json_encode($user_arr);