Complex array in Ruby - ruby

I need to create this structure in ruby
{
"list": {
"ownerList" : [ {
"owner" : "Nacho",
"list" : "MyList"
},
{
"owner" : "Nacho2",
"list" : "MyList2"
}
]
}
}
but I'm not sure how to create a multientry array in ruby. Any ideas?

my_hash = {
owner_list: [
{
owner: "Nacho",
list: "MyList"
},
{
owner: "Nacho",
list: "MyList"
},
]
}
This creates a hash with the data you want. You can then very easily transform it to a json if you like and make operations over it.

Related

Hasura GraphQL UPSERT mutation for nested objects

So I'm trying to construct a mutation for inserting/updating a record for a "Person" along with it's address, email, telephones information into multiple tables, using variables.
mutation insertPerson ($address: [adr_insert_input!]!, $emails: [emails_insert_input!]!) {
insert_info(objects: [{
f_name: "User1",
l_name: "Test"
address: {
data: $address,
on_conflict: {
constraint: person_id_pk,
update_column: [add_text_line1, zip_code]
}
},
emails: {
data: $emails,
on_conflict: {
constraint: person_id_pk,
update_column: [email_text]
}
}
}], on_conflict: {
constraints: person_pk,
update_columns: [f_name, l_name]
}) {
affected_rows
}
}
and my variables are set-up as follows...
{
"address": [{
"add_text_line1": "123 Main Street",
"zip_code": 50501
}],
"emails": [{
"email_text": "FirstLastName#email.com"
}]
}
This works as expected for me (with multiple values in emails array too), but I need to move the f_name & l_name values (whole Person object) into a variable as well. How do I achieve that?
I tried the below mutation this way, but this resulted into two separate inserts & empty values being passed...
mutation insertPerson ($person: person_insert_input!, $address: [adr_insert_input!]!){
insertData(objects: [
$person,
{
address: { data: $address }
}
]) { affected_rows }
}
This resulted to a two separate insertions... First person with empty address, then empty person with address.
How do I achieve the first mutation's result, while using Person Info as part of variables NOT hard-code it into the query itself?
Thank you!
You will need to pass the insert_info objects as the variables
mutation insertPerson ($info_objects: [insert_info_insert_input!]!) {
insert_info(objects: $info_objects, on_conflict: {
constraints: person_pk,
update_columns: [f_name, l_name]
}) {
affected_rows
}
}
And your variables will be an array of the info_objects
{info_objects: [{
f_name: "User1",
l_name: "Test"
address: {
data: [{
"add_text_line1": "123 Main Street",
"zip_code": 50501
}]
},
on_conflict: {
constraint: person_id_pk,
update_column: [add_text_line1, zip_code]
}
},
emails: {
data: [{
email_text: "FirstLastName#email.com"
}],
on_conflict: {
constraint: person_id_pk,
update_column: [email_text]
}
}
}]}

How to find all documents that don't have an array or it is smaller than

I'm trying to find all documents, which either don't have an array tags or the size of the array is smaller than 2. How do I do this? I'm trying this, but doesn't work:
db.collection.find({
'text' => { '$exists' => true }, # I need this one too
'tags' => {
'$or' => [
{ '$exists' => false },
{ '$lt' => ['$size', 2] }
]
}
})
It's Ruby, btw. MongoDB version is 4.
I'm getting:
unknown operator: $or
You can use below query
db.collection.find({
text: { $exists: true },
$or: [{
tags: { $exists: false }
}, {
$expr: { $lt: [{ $size: '$tags' }, 2] }
}]
})
To slightly modify MauriRamone's answer to a smaller version:
db.getCollection('test').find({
$and:[
{"text":{$exists:true} },
{$where: "!this.tags || this.tags.length < 2"}
]
})
However, $where is slow, and other options (such as Anthony's) should be preferred.
Your original query wasn't working because $or only works in expressions, not in fields, and you need an $expr operator for the size.
try using $were in your query, like this:
db.getCollection('test').find({
$and:[
{"text":{$exists:true} },
{
$or:[
{"tags":{$exists:false}},
{$where: "this.tags.length < 2"}
]
}
]
})
I am using Robomongo to test, you should format the query to Ruby.
regards.

ElasticSearch query for items not in given array

I am trying to write a part of a query to filter out any items with a type as "group" and that have a group id that isn't in a given array of ids. I started writing a bool query with a must and must_not but I was getting tripped up on how to write "id not in the given array.
EDIT:
I am actually converting an outdated query using "and" and "not" to be ES 5.5 compatible. Here is the old query that worked.
:and => [
{
term: {
type: 'group'
}
},
{
:not => {
terms: {
group_id: group_ids
}
}
},
{
:not => {
terms: {
user_id: user_ids
}
}
}
]
group_ids and user_ids are arrays.
You probably have not analyzed the arrays with the IDs. You can use a Bool query with a filter clause, and then within that filter start a new bool query with a mustNot clause and within that clause add a terms query with your IDs.
bool: {
must: {
term: {
kind: 'group'
}
},
must_not: [
{
terms: {
group_id: group_ids
}
},
{
terms: {
user_id: user_ids
}
}
]
}

How can i get avg,sum of sub attribute?

I have problem with writing average query!
In my Rethink db, i have some documents in one table like this:
document1:
{
a:{
last:3
},
b:{
last:4
},
c:{
last:6
},
}
document2:
{
a:{
last:7
},
b:{
last:9
},
c:{
last:2
},
}
document3:
{
a:{
last:5
},
b:{
last:8
},
c:{
last:4
},
}
I want to get average of last attribute in every object like this:
{
sum_a_last:15,
sum_b_last:21,
sum_c_last:12,
avg_a_last:5,
avg_b_last:7,
avg_c_last:4
}
What is the query to return this result?
I believe what you're looking for is
r.db('dbName').table('tableName').avg((doc) => doc('a')('last'));
If you're trying to dynamically look for the last member for all objects in a doc there will obviously be more work.
https://rethinkdb.com/api/javascript/avg/

missing type in composite literal in golang/mongodb aggregate query

I want to write mongo query in golang. my mongo query is -
aggregate([
{$match: {$and :
[
{"stream" : "CS"},
{"semester" : "sem3"},
{"section" : "A"}
]
}},
{$unwind: '$atndnc'},
{ $group: { _id:{rollno: "$atndnc.rollno",attend:"$atndnc.attend"},count: { $sum: 1 }}},
{ $project:
{ _id: '$_id.rollno',
'attend' : '$_id.attend',
'count' : '$count'
}}
])
And my Go code is -
cond:=[]bson.M{
bson.M{"$match": bson.M{"$and ":[]interface{}{
bson.M{"stream" : srchobj.Stream},
bson.M{"semester" : srchobj.Semester},
bson.M{"section" : srchobj.Section},
bson.M{"college_id":srchobj.College_id},
bson.M{"date":bson.M{"$gt":srchobj.Startdate,"$lt":srchobj.Enddate}}}}},
bson.M{"$unwind": "$atndnc"},
bson.M{"$group":bson.M{"_id":{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}},"count":bson.M{"$sum":1}}},
bson.M{"$project":bson.M{"_id":"$_id.rollno","count":"$_id.count"}}}
but it give the error "missing type in composite literal" in
bson.M{"$group":bson.M{"_id":{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}},"count":bson.M{"$sum":1}}},
in this line.what should i do now?
You have a missing type declaration on a set of braces in your $group query:
{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend"}}
I would assume should be:
bson.M{"rollno":bson.M{"$atndnc.rollno"},"attend":bson.M{"$atndnc.attend":nil}}
there are also a few other initialization things like initializations with just a string key (remember, a bson.M is just an alias for map[string]interface{}
Thanks for your support.I got the desired output by doing this.
cond :=[]bson.M{
bson.M{"$match": bson.M{
"stream" : srchobj.Stream,
"semester" : srchobj.Semester,
"section" : srchobj.Section,
"college_id":srchobj.College_id,
"date":bson.M{
"$gt":srchobj.Startdate,
"$lt":srchobj.Enddate},
},
},
bson.M{"$unwind": "$atndnc"},
bson.M{"$group":bson.M{
"_id":bson.M{
"rollno":"$atndnc.rollno",
"attend":"$atndnc.attend",
"name":"$atndnc.name",
},
"count":bson.M{"$sum":1},
},
},
bson.M{"$project":bson.M{
"rollno":"$_id.rollno",
"name":"$_id.name",
"count":"$count",
"attend":"$_id.attend",
},
},
bson.M{"$sort":bson.M{"rollno":1}},
}

Resources