Filter documents that do not have a property set - Prisma - prisma

I have this example data:
const example = [
{
productId: 1,
name: "Husdady",
age: 21
},
{
name: "Vereth",
age: 19
},
{
name: "Mikaela",
age: 17
},
{
name: "Richard",
age: 20
},
{
productId: 4,
name: "Markus",
age: 24
},
{
productId: 8,
name: "Cecilia",
age: 18
},
{
productId: 1,
name: "Anton",
age: 16
}
]
console.log(example)
I have a 'User' model in prisma. So what I must achieve is to filter all those users that do not have a defined productId and also filter by productId.
For example, I want to filter all users that have product Id 1 and also all users that do not have a productId defined
I have tried with the following filter
this.prisma.users.findMany({
where: {
OR: [
{ productId: undefined },
{ productId: 1 }
]
}
})
This query gets me all the users that have '1' as the value of their 'productId' but it does not bring me the users that do not have a defined productId.
The expected result of the above query would be:
const result = [
{
productId: 1,
name: "Husdady",
age: 21
},
{
name: "Vereth",
age: 19
},
{
name: "Mikaela",
age: 17
},
{
name: "Richard",
age: 20
},
{
productId: 1,
name: "Anton",
age: 16
}
]
console.log(result)
I only get the users 'Husdady' and 'Anton'
const resultObtained = [
{
productId: 1,
name: "Husdady",
age: 21
},
{
productId: 1,
name: "Anton",
age: 16
}
]
console.log(resultObtained)
How I can resolve this problem?

Related

How can I have array filter count from nested array

Data:
_id: ObjectId(''),
restaurantId: ObjectId(''),
orderId: ObjectId(''),
reviews: [
{
type: "food",
tags: ["good food", "nice food"]
},
{
type: "pricing",
tags: ["best price", "good price"]
}
]
Group by restaurant id
Get total reviews by type: Ex: food: 3, pricing: 2, ambience: 1
Group by type and tags and get counts:
Ex: food-superb: 1, food-loudt:2, pricing-superb: 2, ambience-superb: 1
Expected result:
{
_id: restaurantId,
types: {
food: 4,
....
},
tags: {
nicePrice: 20
}
}

MongoDB : projection matches all element corresponding to query

Supposing the following data format
{
_id: "1234",
tag: "MyTag",
members: [{
name: "James", age: 54
}, {
name: "John", age: 22
}, {
name: "Eric", age: 36
}],
},
{
_id: "7896",
tag: "MyTag2",
members: [{
name: "Philip", age: 6
}, {
name: "Mark", age: 14
}, {
name: "Maya", age: 64
}],
}
How can I request all the person over 30 to get that result
{
_id: "1234",
tag: "MyTag",
members: [{
name: "James", age: 54
}, {
name: "Eric", age: 36
}],
},
{
_id: "7896",
tag: "MyTag2",
members: [{
name: "Maya", age: 64
}],
}
Basically this request
db.MyDB.find({'members':{'$elemMatch':{'age':{'$gt':30}}}}, {'tag:1', 'members.$':1})
but where the .$ operator does not return only the first or each list
(I'm using python api but I think the question applies more generally)
Thanks a lot!
The positional operator $ and the $elemMatch projection operator both only match the first element that matches the query.
If you want to get all elements that match, use aggregation and $filter the array.

Mongoose: Get the data from 2 collections, like get products that have same category type like fruits

I am very new to mongoDB and mongoose and I also know questions like this has been already asked but still I didn't get any luck.
So what I am trying to do is I have 2 collections one is products and second is categories and I am trying to get the products that are of category type: fruits
product.model.js
const mongoose = require('mongoose')
const productSchema = new mongoose.Schema({
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Category'
},
name: {
type: String,
required: true,
unique: true
},
price: {
type: Number,
required: true
},
image: {
type: String,
required: true
},
description: {
type: String,
required: true
}
})
const Product = mongoose.model('Product', productSchema)
module.exports = Product
category.model.js
const mongoose = require('mongoose')
const categorySchema = new mongoose.Schema({
name: {
type: String,
required: true,
unique: true,
lowercase: true
}
})
const Category = mongoose.model('Category', categorySchema)
module.exports = Category
products collecction
[ { _id: 5ffc9795355f3707ec326f51,
name: 'apple',
price: 80,
image: 'apple1.jpg',
description:
'Do you really need description for this ??',
category: 5ffc94e8a7542a37101a119c,
__v: 0 },
{ _id: 5ffd54409793c33b183376b8,
name: 'Beef',
price: 180,
image: 'beef1.jpg',
description: 'Don\'t you dare to ask about beef in india',
category: 5ffc94dda7542a37101a119b,
__v: 0 },
{ _id: 5ffd54969793c33b183376b9,
name: 'Mango',
price: 100,
image: 'mango1.jpg',
description:
'Have some manog because you cannot eat the bottle of slice like katrina kaif do, its crazy',
category: 5ffc94e8a7542a37101a119c,
__v: 0 } ]
categories collection
[ { _id: 5ffc947ea7542a37101a119a, name: 'vegitables', __v: 0 },
{ _id: 5ffc94dda7542a37101a119b, name: 'non-veg', __v: 0 },
{ _id: 5ffc94e8a7542a37101a119c, name: 'fruits', __v: 0 } ]
Now I want to the get the products whose category are fruits
I know I have to use aggregation and lookup for this I also tried but didn't get any luck, this is my code
const Product = require('./models/product')
const Category = require('./models/category')
const test = async () => {
try {
var query = [
{
$lookup: {
from: "product",
localField: "category",
foreignField: "_id",
as: "product"
}
}]
const productCate = await Product.aggregate(query)
console.log(productCate)
// const productCat = await Product.find().populate({
// path: 'category',
// match: {name: 'fruits'}
// }).exec()
// console.log(productCat)
}catch(e) {
}
}
test()
UPDATE-1
I also tried ppuplate but still didn't get the response as expected, this is my code:
const test = async () => {
try {
const productCat = await Product.find().populate({
path: 'category',
match: {name: 'fruits'}
}).exec()
console.log(productCat)
}catch(e) {
}
}
test()
this is my output
[ { _id: 5ffc9795355f3707ec326f51,
name: 'apple',
price: 80,
image: 'apple1.jpg',
description:
'Do you really need description for this, how dumb are you ??',
category: { _id: 5ffc94e8a7542a37101a119c, name: 'fruits', __v: 0 },
__v: 0 },
{ _id: 5ffd54409793c33b183376b8,
name: 'Beef',
price: 180,
image: 'beef1.jpg',
description: 'Don\'t you dare to ask about beef in india',
category: null,
__v: 0 },
{ _id: 5ffd54969793c33b183376b9,
name: 'Mango',
price: 100,
image: 'mango1.jpg',
description:
'Have some manog because you cannot eat the bottle of slice like katrina kaif do, its crazy',
category: { _id: 5ffc94e8a7542a37101a119c, name: 'fruits', __v: 0 },
__v: 0 } ]
Here I also get the beef that is fall under non-veg category but with the category null. Actually I only want the fruits category products.
you can following this code
const test = async () => {
try {
let categoryId = await Category.findOne({name:"fruits"}).select("_id")
const productCat = await Product.find({category:categoryId}).populate(
"category"
).lean()
console.log(productCat)
}catch(e) {
}
}
test()
you can do with with populate match without using aggregation:
Product.find().populate({
path: 'category',
match: { 'name': 'fruits' }
})
.exec()

Assure order when using $skip and $limit in MongoDB

I have data like this in my collection:
...
{ name: 'ad1cvbc', price: 300 },
{ name: 'tbcvbc3', price: 500 },
{ name: 'yjc5vbc', price: 500 },
{ name: 'at7vvbc', price: 500 },
{ name: 'a86v5bc', price: 500 },
{ name: 'a23dvbc', price: 500 },
{ name: 'adth4bc', price: 500 },
{ name: 'e34bc', price: 700 },
...
And I have an aggregate like this:
[
{ $match: { ... } },
{ $sort: { price: -1 } },
{ $skip: x },
{ $limit: 20 }
]
Where x is increased with 20 every single time I wants more data, but the problem is that, because I have multiple price with same value( and I have more than 20) sometimes I get the same document. How cand I assure that the order is the same and I don't get duplicates when I have many rows with the field for the sort having the same value.
Edit: So if I want to get 3 items each time I may have the following results:
1st call result:
{ name: 'ad1cvbc', price: 300 },
{ name: 'tbcvbc3', price: 500 },
{ name: 'yjc5vbc', price: 500 } // <- this
2st call result:
{ name: 'a23dvbc', price: 500 },
{ name: 'yjc5vbc', price: 500 }, // <- this
{ name: 'at7vvbc', price: 500 }
1 document is repeated because MongoDB doesn't get each time the items in order when the documents has the same value for the sort field.
Something like
[
{ $match: { ... } },
{ $sort: { name:-1, price: -1 } },
{ $skip: x },
{ $limit: x + 20 }
]

How to redirect to a nested dynamic segments in EMberjs

If we have several books,each books contains several chapters and each chapter contains several pages.
In an App,
when user navigate to
"/home"
list all the books,clicking a book(eg:book_1) will directly "linkTo"
"/book_1/chapter_1/page_1"
show the content of "chapter_1/page_1" within the selected book.
I am now trying to use the "redirect" hook,but I am confused with these:
1,How to sent muti params to a redirect hook;
2,How to update the URL correctly after redirecting?
3,What is the "Ember way" to do this?
_BOOK MODEL__
App.Book = DS.Model.extend({
name: DS.attr('string'),
chapters: DS.hasMany('chapter',{async:true}),
color: DS.attr('')
});
App.Chapter = DS.Model.extend({
name: DS.attr('string'),
author: DS.attr(''),
pages: DS.hasMany('page',{async:true})
});
App.Page = DS.Model.extend({
name: DS.attr('string'),
});
App.Book.FIXTURES = [
{
id: 1,
name: 'book1',
color: 'red',
chapters: [1,2]
},
{
id: 2,
name: 'book2',
color: 'blue',
chapters: [3,4]
}
];
App.Chapter.FIXTURES = [
{
id: 1,
name: 'Chapter1',
author: 'jhon',
pages:[1,2]
},
{
id: 2,
name: 'Chapter2',
author: 'jhon',
pages:[3,4]
},
{
id: 3,
name: 'Chapter3',
author: 'peter',
pages:[5,6]
},
{
id: 4,
name: 'Chapter4',
author: 'tom',
pages:[7,8]
}
];
App.Page.FIXTURES = [
{
id: 1,
name: 'page1',
},
{
id: 2,
name: 'page2',
},
{
id: 3,
name: 'page3',
},
{
id: 4,
name: 'page4',
},
{
id: 5,
name: 'page5',
},
{
id: 6,
name: 'page6',
},
{
id: 7,
name: 'page7',
},
{
id: 8,
name: 'page8',
}
];
redirect is deprecated, use the afterModel hook. I'm sending in ids of 1 and 1 to the chapter and page route, which should hit their model hooks. How is your data separated, does the book model have all the necessary info?
http://emberjs.jsbin.com/uDiLIkij/6/edit
afterModel: function(model, transition){
console.log(transition.targetName);
if(transition.targetName=='book.index'){
var self = this;
model.get('chapters').then(function(chs){
var ch = chs.get('firstObject');
ch.get('pages').then(function(pages){
var page = pages.get('firstObject');
self.transitionTo('page', model, ch, page);
});
});
transition.abort();
}
},