Fetch users data with related clients data in Yiii2 api - yii2

I need to get an API response, where each client row has its associated users' data in it. like this:
clients: [
{
id: 1
name: 'client_1',
users: [{ id: 1, name: 'user_1', clients_id: 1}, { id: 2, name: 'user_2',
clients_id: 1 }],
},
{
id: 2
name: 'client_2',
users: [{ id: 3, name: 'user_3', clients_id: 2}, { id: 4, name: 'user_4',
clients_id: 2 }],
},
]
How can I write Yii2 code for this result? Do query builder works here or do I need to use MySQL syntax?

I believe you have two tables those are related some how. You can achieve it by defining client relation in users table. One you defined the relation define extrafields function and add the relation there.
In url use expand query param and mention your relation there.
You are done!
Sample URLhttp://localhost/users?fields=id,email&expand=profile
Check the documentation

Related

Adding multiple entries/rows with knex mysql

I get the following data from the req.body:
{
"user_id": "1",
"user_name": "jkalandarov",
"email": "jkalandarov#gmail.com",
"courses": [
{
"course_id": 1,
"course_name": "English",
"course_price": 265
},
{
"course_id": 2,
"course_name": "Node.js",
"course_price": 200
},
{
"course_id": 3,
"course_name": "Backend Developement",
"course_price": 300
}
]
}
I want to insert this data into three rows with the help of knex into mysql database table like this with a single query:
Any ideas?
Thanks in advance!
Assuming you already have your knex connection set up, it should simply allow you to pass an array of objects into the insert function to insert multiple rows with a single statement. https://knexjs.org/#Builder-insert
Step 1: Build an array of objects
const objectsToInsert = req.body.courses.map(course => {
return {
user_id: req.body.user_id,
user_name: req.body.user_name,
email: req.body.email,
...course
}
});
Step 2: Insert them using your knex connection
await knex('your_table_name').insert(objectsToInsert);
This should insert those three rows into your table in a single query.
As this data is coming directly from the request body it is obviously also a good idea to add some validation here but that feels out of scope for your original question.

How can i make a mongoDB subdocument have an unique id or incremented id?

Solved
I am having this MongoDB document:
{
_id: "5e3bf72db5074c1e205409f5",
todos: [
{
title: "title",
description: "description",
state: "state",
priority: "priority"
}
],
title: "test project"
}
and I want to keep the main '_id:' property for the project but also add an "_id:" or something of that sorts to my todos so that I can do CRUD operations on them alone easier. Is there a way of making a unique id or autoincremented id for them? The final result would look like this
Is there a way to do this? also, any other suggestions are appreciated.
{
_id: another unique id or autoincrement key,
title: "title",
description: "description",
state: "state",
priority: "priority"
}

Solr grouped query pagination not working properly. [Solr, Lucene]

I have grouped my solr documents by a field family.
the solr query for getting first 20 groups is as follows
/select?q=*:*&group=true&group.field=family&group.ngroups=true&start=0&group.limit=1
Result of this query is 20 groups as following
responseHeader: {
zkConnected: true,
status: 0,
QTime: 1260,
params: {
q: "*:*",
group.limit: "1",
start: "0",
group.ngroups: "true",
group.field: "family",
group: "true"
}
},
grouped: {
family: {
matches: 464779,
ngroups: 396324,
groups: [
{
groupValue: "__fam__ME.EA.HE.728928",
doclist: {
numFound: 1,
start: 0,
maxScore: 1,
docs: [
{
sku: "ME.EA.HE.728928",
title: "Rexton Pocket Family Hearing Instrument Fusion",
family: "__fam__ME.EA.HE.728928",
brand: "Rexton",
brandId: "6739",
inStock: false,
bulkDiscount: false,
quoteOnly: false,
cats: [
"Hearing Machine & Components",
"Health & Personal Care",
"Medical Supplies & Equipment"
],
leafCatIds: [
"6038"
],
parentCatIds: [
"6259",
"4913"
],
Type__attr__: "Pocket Family",
Type of Products__attr__: "Hearing Instrument",
price: 3790,
discount: 40,
createdAt: "2016-02-18T04:51:36Z",
moq: 1,
offerPrice: 2255,
suggestKeywords: [
"Rexton",
"Pocket Family",
"Rexton Pocket Family"
],
suggestPayload: "6038,Hearing Machine & Components",
_version_: 1548082328946868200
}
]
}
},
Just the thing to notice in this result is the value of ngroups which is 396324
But when i want to get data of last pages i would hit this query on Solr
select?q=*:*&group=true&group.field=family&group.ngroups=true&start=396320&group.limit=1
{
responseHeader: {
zkConnected: true,
status: 0,
QTime: 5238,
params: {
q: "*:*",
group.limit: "1",
start: "396320",
group.ngroups: "true",
group.field: "family",
group: "true"
}
},
grouped: {
family: {
matches: 464779,
ngroups: 396324,
groups: [ ]
}
}
}
0 results when i set start to 396320. There must be 5 documents in the result. The actual number of groups are 386887. Why is ngroups incorrect?
btw this issue is not present in my local solr server i have setup up. just shows up in solr cloud on the test env
This is a known issue with grouping across distributed nodes (which is what happens in SolrCloud mode):
Grouping is supported for distributed searches, with some caveats:
Currently group.func is is not supported in any distributed searches
group.ngroups and group.facet require that all documents in each group must be co-located on the same shard in order for accurate counts to be returned. Document routing via composite keys can be a useful solution in many situations.
The most direct solution is to use the family as a part of the routing key, ensuring that all identical family values will end up on the same node. As it seems that the number of distinct family values are very high compared to the number of nodes, this should still ensure that you have a good distribution of documents across nodes.
Depending on what you're actually trying to do, there might be other alternative solutions as well (if you just want a count, using a JSON facet might be a good solution).

Sequelize: How to return relationships as JSON attribute?

I have a simple database of articles and authors.
Each article is connected to author(s) through a belongsToMany relationship, for example:
Articles
id: 1
title: Test
Authors
id: 1
name: Foo
id: 2
name: Bar
Say, for example, that the article is joined to both authors.
Using sequelize, how can I have Articles.findAll() return the authors along with its details, for example:
"articles": [
{
"id": 1,
"title": "Test",
"author_ids": "[1,2]"
}
]
Use the include option in your query:
Articles.findAll({
include: [Author]
}).then(function(articles) {
console.log(articles[0].authors[0].author_id);
});

REST api design to retrieve summary information

I have a scenario in which I have REST API which manages a Resource which we will call Group.
A Group is similar in concept to a discussion forum in Google Groups.
Now I have two GET access method which I believe needs separate representations.
The 1st GET access method retrieves the minimal amount of information about a Group.
Given a group_id it should return a minimal amount of information like
{
group_id: "5t7yu8i9io0op",
group_name: "Android Developers",
is_moderated: true,
number_of_users: 34,
new_messages: 5,
icon: "http://boo.com/pic.png"
}
The 2nd GET access method retrives summary information which are more statistical in nature like:
{
group_id: "5t7yu8i9io0op",
top_ranking_users: {
[ { user: "george", posts: 789, rank: 1 },
{ user: "joel", posts: 560, rank: 2 } ...]
},
popular_topics: {
[ ... ]
}
}
I want to separate these data access methods and I'm currently planning on this design:
GET /group/:group_id/
GET /group/:group_id/stat
Only the latter will return the statistical information about the group. What do you think about this ?
I don't see a problem with your approach. Since the statistics are basically separate data, you could treat the stats as a separate resource, too, providing a URI like
GET /stat/:group_id
Additionally you can cross reference your resources (meaning a group links to the corresponding stat resource and vice versa):
GET /group/5t7yu8i9io0op
{
group_id: "5t7yu8i9io0op",
group_name: "Android Developers",
is_moderated: true,
number_of_users: 34,
new_messages: 5,
icon: "http://boo.com/pic.png",
stats: "http://mydomain.com/stat/5t7yu8i9io0op"
}
GET /stat/5t7yu8i9io0op
{
group: "http://mydomain.com/group/5t7yu8i9io0op",
top_ranking_users: {
[ { user: "george", posts: 789, rank: 1 },
{ user: "joel", posts: 560, rank: 2 } ...]
},
popular_topics: {
[ ... ]
}
}
What would be even better would be if you embedded the link to the statistics in the group summary:
{
group_id: "5t7yu8i9io0op",
group_name: "Android Developers",
is_moderated: true,
number_of_users: 34,
new_messages: 5,
icon: "http://boo.com/pic.png"
stats_link : "http://whatever.who/cares"
}