Setting extraFields in rest api yii2 - rest

public function fields()
{
return [
'field' => 'field',
];
}
public function extraFields()
{
return [
'users',
];
}
return:
{ "field": "field", "users": { "id": 1, "name": "user" } }
how to exclude id?
public function extraFields()
{
return [
'users' => function($model){
return [
'name' => $model->users->name,
];
}
];
}
return:
{ "field": "field", "users": { "name": null } }
how to fill in the name field correctly or how to customize field output filtering?

Option can be overwrite field() method in User model:
public function fields()
{
$fields = parent::fields();
if ($something) {
unset($fields['id']);
}
return $fields;
}

Related

Search MongoDB autocomplete filtered

I want to search autocomplete on the following fields :contactfirstname, contactlastname and name
Also, want to filter based on userid(s) first then perform autocomplete search
Issue:
Without filter criteria, autocomplete is working fine
With filter criteria in compound query not working as getting empty array
Can anyone help please?
exports.userNameCitySearchAutocomplete = async function (req, res) {
try {
const { userNameCityQueryparam } = req.query;
console.log("search query param", userNameCityQueryparam);
const agg = [
{
$search: {
index: 'userNameCity',
'compound': {
"filter": [{
"text": {
"query": ["6271f2bb79cd80194c81f631"],
"path": "_id",
}
}],
"should": [
{
//search on user name
autocomplete: {
query: userNameCityQueryparam,
path: 'name',
fuzzy: {
maxEdits: 2,
prefixLength: 3
}
}},
//search on user city
{
autocomplete: {
query: userNameCityQueryparam,
path: 'city',
fuzzy: {
maxEdits: 2,
prefixLength: 3
}
},
}
,
//search on user contact first name
{
autocomplete: {
query: userNameCityQueryparam,
path: 'contactfirstname',
fuzzy: {
maxEdits: 2,
prefixLength: 3
}
},
}
,
//search on user contact last name
{
autocomplete: {
query: userNameCityQueryparam,
path: 'contactlastname',
fuzzy: {
maxEdits: 2,
prefixLength: 3
}
},
}
],
"minimumShouldMatch": 1
}
}
}
]
const response = await User.aggregate(agg);
return res.json(response);
// res.send(response);
} catch (error) {
console.log("autocomplete search error", error);
return res.json([]);
}
};
Index details in mongodb:
{
"mappings": {
"dynamic": false,
"fields": {
"_id": {
"type": "string"
},
"city": {
"type": "autocomplete"
},
"contactfirstname": {
"type": "autocomplete"
},
"contactlastname": {
"type": "autocomplete"
},
"name": {
"type": "autocomplete"
}
}
}
}
Image of collection in mongodb
image of empty array
for anyone looking for solution to this,
You can use the MQL where clause in your pipeline stage definition.
{
$match: {
email:"email#domain.com"
}
}
check here for an example

Laravel Mongodb Messenger relations data not filtering

I have 3 collection instances with belongsToMany relations.
I want to filter data from all 3 collections but not sure how.
Collection Structure.
Payment:
{
"_id": "5ba3c8f7c2ab9b3bed20ae22",
"code": "GHFH",
"amount": "345.00"
}
User:
{
"_id": "5ba3c87cc2ab9b34be139382",
"name": "Jack",
"email": "Pd#gmail.com",
"payment_ids": [
"5ba3c8f7c2ab9b3bed20ae22"
]
}
Customer:
{
"_id": "23c34c87cc2ab9b34b3423423",
"name": "cfb",
"email": "Psfsdd#gmail.com",
"payment_ids": [
"5ba3c8f7c2ab9b3bed20ae22"
]
}
I have create below query.
$cruds = payment::with([
'user' => function ($query) {
$query->orWhere('name','like', "%'".$search."'%");
},
'customer' => function ($query) {
$query->orWhere('name','like', "%'".$search."'%");
}
])
->orWhere('code','like', "%'".$search."'%")
->orWhere('amount', 'like', "%'".$search."'%")
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
Please Suggest.
I have change in query.
$cruds = payment::with([
'user' => function ($query) {
$query->where('name','like', "%{$search}%");
},
'customer' => function ($query) {
$query->where('name','like', "%{$search}%");
}
])
->where('code','like', "%{$search}%")
->where('amount', 'like', "%{$search}%")
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();

group by properties and sum of values between nested json and array of objects

I have users array with their name,
var users = [{'name':'zulekha'}, {'name':'deepika'}];
I am fetching worklogged by each user from jira APIs. So I am getting object like this.
var worklogResult = {
"issues": [
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "zulekha",
},
"timeSpentSeconds": 180
},
{
"author": {
"name": "deepika",
},
"timeSpentSeconds": 210
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "deepika",
},
"timeSpentSeconds": 140
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "zulekha",
},
"timeSpentSeconds": 600,
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": []
}
}
}
]
}
Now I want to match worklogResult with users in such a way that I can get following output.
output = [{'name':'zulekha','timeSpentSeconds':780}, {'name':'deepika', 'timeSpentSeconds':350}]
Can anyone suggest me how to achieve this?
use _.flatMap to flat nested objects
_.chain(worklogResult.issues)
.flatMap('fields.worklog.worklogs')
.thru(function(spents) {
return _.map(users, function(user) {
return _.merge(user, {
timeSpentSeconds: _.chain(spents)
.filter(['author.name', user.name])
.map('timeSpentSeconds')
.sum()
.value()
})
})
})
.value()

Yii2 REST choosing fields in extrafields

From the yii2 definite guide:
public function fields()
{
return ['id', 'email'];
}
public function extraFields()
{
return ['profile'];
}
the request with http://localhost/users?fields=id,email&expand=profile may return the following JSON data:
[
{
"id": 100,
"email": "100#example.com",
"profile": {
"id": 100,
"age": 30,
}
},
...
]
How can I tune extraFields (or maybe something else) to get only one field (for example, age) in profile section of response in this sample?
This feature will be added in Yii 2.0.14
https://github.com/yiisoft/yii2/pull/14219
Example API request will be work like this: users?fields=id,email&expand=profile.age
Edit: For now you can use something like this:
public function extraFields()
{
return [
'profileAge' => function($item){
return $item->profile->age
}
];
}
with request: http://localhost/users?fields=id,email&expand=profileAge
The first thing that came to mind
public function extraFields(){
return [
'profile' => function($item){
return [
'age' => $item->profile->age
];
}
];
}

Finding multiple docs using same id not working, using meteor + react and mongoDB

How do I get the email address of the students in the same class_id, take it as there are more then 2 students in different class in the DB as well?
I have this but it return empty array []
Meteor.users.find({"course_learn_list.$.class_id": {$in: [classId]}},
{field: {"emails.address": 1}}
).fetch()
Collections
{
"_id": "LMZiLKs2MRhZiiwoS",
"course_learn_list": [
{
"course_id": "M8EiKfxAAzy25WmFH",
"class_id": "jePhNgEuXLM3ZCt98"
},
{
"course_id": "5hbwrfbfxAAzy2nrg",
"class_id": "dfbfnEuXLM3fngndn"
}
],
"emails": [
{
"address": "student1#gmail.com",
"verified": false
}
]
},
{
"_id": "JgfdLKs2MRhZJgfNgk",
"course_learn_list": [
{
"course_id": "M8EiKfxAAzy25WmFH",
"class_id": "jePhNgEuXLM3ZCt98"
},
{
"course_id": "5hbwrfbfxAAzy2nrg",
"class_id": "dfbfnEuXLM3fngndn"
}
],
"emails": [
{
"address": "student2#gmail.com",
"verified": false
}
]
}
I think you want:
Meteor.users.find({ "course_learn_list.class_id": classId },
{ "course_learn_list.$": 1, "emails.address": 1 }).fetch()
This should find the first instance in each course_learn_list array where the classId is your classId.
In this case you probably don't need to use a projection to get the right answer. Here's an example of extracting the verified email addresses using only the . operator in the selector:
const ids = ['jePhNgEuXLM3ZCt98', 'some-other-id'];
const emails =
Meteor.users.find({ 'course_learn_list.class_id': { $in: ids } })
.fetch()
.map(user => _.findWhere(user.emails, { verified: true }).address);
This works for me!
Meteor.publish("getMyClassStudents", function(classId) {
console.log("Publish getMyClassStudents")
var self = this
if (self.userId) {
var data = Meteor.users.find({
"course_learn_list.class_id": classId
}, {
"fields": {
"emails.address": 1
}
})
return data
}
else {
return self.ready()
}
})