how to retrieve the child of the parent in n1ql query - couchbase

I am planning to retrieve the child elements of the parent based on some condition. How can i retrieve it, being inside the array of array objects.
SELECT ARRAY {s.name,s.id} FOR s IN t.countryDetails.stateInfo END AS stateDetails
FROM test AS t
WHERE t.type = "countries" and t.countryDetails.name = 'US';
this is the actual json document i am trying to query:
{
"type":"countries",
"docName":"CountryData",
"countryDetails":[
{
"name":"US",
"code":"+1",
"stateInfo":[
{
"name":"Florida",
"id":"1212"
},
{
"name":"NewYork",
"id":"1214"
}
]
},
{
"name":"France",
"code":"+33",
"stateInfo":[
{
"name":"Grand Est",
"id":"5212"
},
{
"name":"Brittany",
"id":"5214"
}
]
}
]
}
I am expecting the following output to bring out the country state details of US only:
[
{
"name":"Florida",
"id":"1212"
},
{
"name":"NewYork",
"id":"1214"
}
]

If you your ConutryDetails has single entry per country use the following
SELECT FIRST s.stateInfo FOR IN t.countryDetails WHEN s.name = "US" END AS stateDetails
FROM test AS t
WHERE t.type = "countries"
AND ANY v IN t.countryDetails SATISFIES v.name = 'US' END;
OR
SELECT cd.stateInfo AS stateDetails
FROM test AS t
UNNEST t.countryDetails AS cd
WHERE t.type = "countries" AND cd.name = 'US';

Related

django many to many queriying

I am building an e-commerce website using Django, my models is like bellow :
class ProductAttribute(models.Model):
product=models.ForeignKey(Product,on_delete=models.CASCADE)
attributes_values = models.ManyToManyField(AttributeValue,verbose_name="Liste des attributs")
stock = models.PositiveIntegerField()
price = models.PositiveIntegerField(verbose_name="Prix")
image = models.ImageField(blank=True,null=True,upload_to="products")
class AttributeValue(models.Model):
attribute=models.ForeignKey(Attribute,on_delete=models.CASCADE,verbose_name="Attribut")
value = models.CharField(max_length=50,verbose_name="Valeur")
class Attribute(models.Model):
name = models.CharField(max_length=50,verbose_name="Nom")
my view.py
def getatts(request,product_id):
products_with_attributes=ProductAttribute.objects.filter(product__id=product_id)
res=#..... missing code to get attributes with values
return res
In the front end i want to retrieve attributes of a particular product to get them by order, to use them in select (ex:size,color choices) , for example if the query set of ProductAttribute is like:
[{id:1,product:1,attributes_values:[3,4],...},{id:1,product:1,attributes_values:[5,6],...}]
the result in JSON would be like so:
{
result:[
{
key: "color", // attribute.name
values: [
{id: 1, value: "Red",
choices:{
key:"size", // second attribute.name
values:[{id:3,value:"L"},{id:4,value:"XL"}]
}
},
{id: 2, value: "Black",
choices:{
key:"size",
values:[{id:5,value:"M"},{id:6,value:"XXL"}]
}
},
]
}
]
}
Note: I am using MYSQL as database
this is a dirty way of doing it and it is static way (max two attribute values) is there any way to do it using Django ORM:
products=ProductAttribute.objects.filter(product__id=id)
res={}
keys=[]
values=[]
for attribute_value in products.first().attributes_values.all():
keys.append({"id":attribute_value.attribute.id,"name":attribute_value.attribute.name})
res["id"]=keys[0]["id"]
res["name"]=keys[0]["name"]
# print(res)
for p in products:
attributes_values=p.attributes_values.all()
# print([ { "id":attv.id,"value":attv.value, "attribute_id":attv.attribute.id, "attribute_name":attv.attribute.name } for attv in attributes_values ])
for attv in attributes_values:
if attv.attribute.id==res["id"]:
exists=False
for v in values:
if v["id"]==attv.id:
exists=True
if not exists:
if len(keys)>1:
first_attribute={ "id":attv.id,"value":attv.value}
first_attribute["sub"]={"id":keys[1]["id"],"name":keys[1]["name"],"values":[]}
for pp in products:
for attv2 in pp.attributes_values.filter(productattribute__id__in= products.filter(attributes_values__id=attv.id).values("id")):
if attv2.attribute.id!=res["id"]:
exists2=False
for sub_value in first_attribute["sub"]["values"]:
if sub_value["id"]==attv2.id:
exists2=True
if not exists2:
first_attribute["sub"]["values"].append({"id":attv2.id,"value":attv2.value})
# first_attribute["sub"]["values"]
# p.attributes_values.all()[1]
values.append(first_attribute)
else:
values.append({ "id":attv.id,"value":attv.value,"sub":{}})
print(attv.attribute.id)
res["values"]=values
print(res)

Field value showing null value

const book1 = this.state.books[0]; //giving one book
console.log(book1); //output->{id: 1, bookname: "Physics", price: 600, author: "ABC", pages: 567, …}
const {id,bookname,price,author,pages,category} = {book1};
console.log(price); //output->undefined
I have already tried a lot of things. How To get the value of particular property?
Here is the JSON file:
[
{
"id": 1,
"bookname": "Physics",
"price": 600,
"author": "ABC",
"pages": 567,
"category" : "Science"
}
]
The JavaScript object destructuring shown is invalid, because of the curly braces around book1.
Remove those braces:
const { id, bookname, price, author, pages, category } = book1;
Here's a simpler example:
> const book = { price: 600 }
undefined
> const { price } = book
undefined
> price
600
Yes, as Jake mentioned, what you're trying to do here is called destructuring assignment. So as per the correct syntax,
const { id, bookname, price, author, pages, category } = book1;
this would actually mean,
const id=book1.id
const bookname=book1.bookname
And so on. You could have a look at https://javascript.info/destructuring-assignment for more information on destructuring assignment.

Convert SQL query to sequelize query with multiple tables

I've been at this for several days attempting to convert what I thought was a relatively simple SQL query into sequelize format. I cannot seem to figure it out for the life of me. I'm relatively new to sequelize, and my SQL skills can use some help as well.
Any help is greatly appreciated, thanks!
Here is the SQL query I have (which works for what I'm attempting to do) which I'm struggling to get to work in sequelize:
SELECT
book.id,
book.author,
book.title,
book_type.type,
book_sub_type.sub_type,
book_location.location,
book_language.language
FROM book
INNER JOIN book_type ON book.book_type_id = book_type.id
INNER JOIN book_sub_type ON book.book_sub_type_id = book_sub_type.id
INNER JOIN book_location ON book.book_location_id = book_location.id
INNER JOIN book_language ON book.book_language_id = book_language.id
WHERE
book.author LIKE '%history%' OR
book.title LIKE '%history%' OR
book_type.type LIKE '%history%' OR
book_sub_type.sub_type LIKE '%history%' OR
book_language.language LIKE '%history%' OR
book_location.location LIKE '%history%'
ORDER BY book_type.type, book_sub_type.sub_type;
Here is as far as I have gotten (this sequelize query returns 0 results because it is searching for the substring "history" in all columns, instead of at least one column):
const books = await Book.findAll({
where: {
[Op.or]: [
{author: { [Op.substring]: 'history' }},
{title: { [Op.substring]: 'history' }}
]
},
attributes: ['id', 'author', 'title'],
include: [
{
model: BookType,
attributes: ['type'],
where: {
type: { [Op.substring]: 'history' }
}
},
{
model: BookSubType,
attributes: ['sub_type'],
where: {
sub_type: { [Op.substring]: 'history' }
}
},
{
model: BookLanguage,
attributes: ['language'],
where: {
language: { [Op.substring]: 'history' }
}
},
{
model: BookLocation,
attributes: ['location'],
where: {
location: { [Op.substring]: 'history' }
}
},
]
});
My schema is as follows:
`book` table columns:
`id`, `author`, `title`, `book_type_id`, `book_sub_type_id`,
`book_language_id`, `book_location_id`
`book_type` table columns:
`id`, `type`
`book_sub_type` table columns:
`id`, `sub_type`
`book_location` table columns:
`id`, `location`
`book_language` table columns:
`id`, `language`
In sequelize, I have the following relationships established:
Book.belongsTo(BookType);
Book.belongsTo(BookSubType);
Book.belongsTo(BookLanguage);
Book.belongsTo(BookLocation);
BookType.hasMany(Book);
BookSubType.hasMany(Book);
BookLanguage.hasMany(Book);
BookLocation.hasMany(Book);
The output should be 7 columns:
book.id, book.author, book.title, book_type.type, book_sub_type.sub_type, book_location.location, book_language.language
Sequelize build a SQL with a conditions in JOINs, so this is not good aproach. You should remove all where conditions from includes. There was a way in a sequelize <4.0.0 to write conditions to subquery using syntax
where: {
$or: [{
'$book.sub_type$$': 'history'
}, {
'$book_type.type$': 'history'
}]
}
but I think this is not longer supported. Only way would be a custom query or use a sequelize literal in where object.
where: {
[Op.or]: [{
Sequelize.literal(`book_type.type LIKE ${history}`)
}, {
Sequelize.literal(`book_sub_type.sub_type LIKE ${history}`)
}]
}
Keep in mind that with this approach there is a risk of SQL injection so you should validate an input or use some escape character strategy. Check sequelize raw queries and seqeulize literal

Translate MYSQL query to mongodb using $Lookup

I am new to Mongodb and I have to move my SQL Queries to mongodb now. I read the document and gained enough knowledge on writing mongodb QUeries but coming from MYSQL it will take time to get expertise on framing Mongo Queries.
I am trying to convert this query to Mongo for now using $Lookup
select * from orig_tbl emas
inner join cust-tbl_after_cleanup tmclient
on emas.state = tmclient.province
and emas.cons_city = tmclient.city
where
emas.state = 'VT' and
emas.can_match_address like concat('%',tmclient.street,'%')
and emas.can_cmp_name like concat('%',tmclient.name,'%')
and emas.can_match_address like concat('%',tmclient.house_num,'%')
and emas.can_match_address like concat('%',tmclient.postal_code,'%')
and emas.cons_city like concat('%',tmclient.city,'%')
and emas.State like concat('%',tmclient.province,'%')
group by tmclient.id,tmclient.name
As you can see I'm doing an inner join on multiple conditions and then doing a partial string match on number of cloumns. From the document I got to know how to do a multiple condition join but not sure how to do partial string match
Code so far:
aggregate(
[
{
'$match' : { 'name' : 'Walmart' }
},
{
'$lookup':
{
'from': 'entity_map_all_states',
'let': { 'order_city': "$city", 'order_qty': "$province" },
'pipeline': [
{ '$match':
{ '$expr':
{ '$and':
[
{ '$eq': [ "$cons_city", "$$order_city" ] },
{ '$eq': [ "$State", "$$order_qty" ] }
]
}
}
}
],
'as': "stockdata"
}
}
] )

Querying couchbase by passing parameter

I am having couchbase report documents stored in below format:
{
"agree_allowed":true,
"assigned_by":"",
"assigned_to":"",
"closed":[
],
"comments_allowed":true,
"details":"Test",
"email":"",
"status":"In Progress",
"subscribed":{
"user_cfd29b81f0263a380507":true,
"user_cfd29b81f0263a380508":true,
"user_cfd29b81f0263a380509":true,
"user_cfd29b81f0263a3805010":true
},
"summary":"Test",
"time_open":0,
"timestamp":"2015-07-17T15:34:30.864Z",
"type":"report",
"user_id":"user_cfd29b81f0263a380507",
"username":"test17"
}
json contain subscribed filed, it is list of user_id who follow reports.
Problem is i have to emit report document if subscribed field contain user_id, if i pass user_id ='user_cfd29b81f0263a380507' pass as key parameter. i am wondering how can use user_id to compare in view
here is the code i write:-
function map(doc, meta) {
if (doc.type == 'report' && doc.subscribed) {
for (var user_id in doc.subscribed) {
emit(doc.user_id, doc);
}
}
}
but it didn't return expected result.
Can anybody help.
If I understand your question I think you want the ability to query the users who have subscribed.
If that is the case the view code is wrong it is submitting doc.user_id and not user_id, which is the variable you assign values to in the loop but never use. In any case I think it would be better to use a different names to avoid confusion.
function map(doc, meta) {
if (doc.type == 'report' && doc.subscribed) {
for (var subscriber in doc.subscribed) {
emit(subscriber);
}
}
}
To query the users who have subscribed you would use key=user_cfd29b81f0263a380507. The result would be:
{
"total_rows": 4,
"rows": [
{
"id": "docs",
"key": "user_cfd29b81f0263a380507",
"value": null
}
]
}