postgresql json array index - arrays

I have data for customers with more than one adresses with json representation like this:
{
"firstName" : "Max",
"lastName" : "Mustermann",
"addresses" : [{
"city" : "München",
"houseNumber" : "1",
"postalCode" : "87654",
"street" : "Leopoldstraße",
}, {
"city" : "Berlin",
"houseNumber" : "2a",
"postalCode" : "12345",
"street" : "Kurfürstendamm",
}
]
}
these json is stored in a column named json of datatype json in a table named customer.
I want to query like this:
SELECT *
FROM customer cust,
json_array_elements(cust.json#>'{addresses}') as adr
WHERE adr->>'city' like '%erlin'
and adr->>'street' like '%urf%';
Query works fine ... but can't create index that postgresql 9.3.4 can use.
Any idea?

Related

Find only the documents which have two embedded documents

I'm using Mongodb to analysee a Nobel prizes dataset which documents look like these:
> db.laureate.find().pretty().limit(1)
{
"_id" : ObjectId("604bc8c847d640142f02b3b1"),
"id" : "1",
"firstname" : "Wilhelm Conrad",
"surname" : "Röntgen",
"born" : "1845-03-27",
"died" : "1923-02-10",
"bornCountry" : "Prussia (now Germany)",
"bornCountryCode" : "DE",
"bornCity" : "Lennep (now Remscheid)",
"diedCountry" : "Germany",
"diedCountryCode" : "DE",
"diedCity" : "Munich",
"gender" : "male",
"prizes" : [
{
"year" : "1901",
"category" : "physics",
"share" : "1",
"motivation" : "\"in recognition of the extraordinary services he has rendered by the discovery of the remarkable rays subsequently named after him\"",
"affiliations" : [
{
"name" : "Munich University",
"city" : "Munich",
"country" : "Germany"
}
]
}
]
}
As you see the column "prizes" has embedded documents and the query I am trying to do is finding only those laureates who won two prizes (which I already know to be Marie Curie and Linus Pauling) can you help me with that?
Thanks in advance!
The $size operator should work fine for this. You could read about it if you want in this link: https://docs.mongodb.com/manual/reference/operator/query/size/
Your new query:
db.laureate.find({prizes: {$size: 2}}).pretty().limit(1)

MongoDB - Array element as variable

Lets say here is the same document:
{
"_id" : 1.0,
"custname" : "metlife",
"address" : {
"city" : "Bangalore",
"country" : "INDIA"
}
}
And if I want to push an extra field to this document, something like below:
db.customers.updateMany(
{"address.country":"INDIA"},
{$push : {city: "$address.country"}}
)
It results in wrong update:
{
"_id" : 1.0,
"custname" : "metlife",
"address" : {
"city" : "Bangalore",
"country" : "INDIA"
},
"city" : "$address.city"
}
Instead of this:
{
"_id" : 1.0,
"custname" : "metlife",
"address" : {
"city" : "Bangalore",
"country" : "INDIA"
},
"city" : "Bangalore"
}
How do I achieve the above result?
You can't refer to other field values in update currently (more here). There is a workaround in aggregation framework (using $out) but it will replace entire collection.
I think that you can consider using $rename in your case. It will not add new field but it can move city to the top level of your document.
db.customers.updateMany({"address.country":"INDIA"}, {$rename: {"address.city": "city"}})
will give you following structure:
{ "_id" : 1, "custname" : "metlife", "address" : { "country" : "INDIA" }, "city" : "Bangalore" }
like #mickl said : You can't refer to other field values in update currently,
you have to iterate through your collection to update the documents, try this :
db.eval(function() {
db.collection.find({"address.country":"INDIA"}).forEach(function(e) {
e.city= e.address.city;
db.collection.save(e);
});
});
Keep in mind that this will block the DB until all updates are done.
try this
db.customers.updateMany(
{"address.country":"INDIA"},
{$push : {city: "address.country"}}
)
remove $ sign

Flatten a document in document db

I have a document in document db that has a property that is an array of an object. I would like to flatten it and get a single property in all the objects in terms of an array.
eg:
{
"name" : "blah",
"address" : [
{
"type" : "home",
"location" : "123 st"
},
{
"type" : "work",
"location" : "321 st"
}
]
}
-> What I want
[
{
"name" : "blah",
"locations" : [ "123 st", "321 st" ]
}
]
You could try to define and use User-defined function to extract locations info.
And then you could call this User-defined function from inside your query.

Getting array length in mongodb?

{
"_id" : 654321,
"first_name" : "John",
"last_name" : "Doe",
"interested_by" : [ "electronics", "sports", "music" ],
"address" : {
"name" : "John Doe",
"company" : "Resultri",
"street" : "1015 Mapple Street",
"city" : "San Francisco",
"state" : "CA",
"zip_code" : 94105
}
}
How can i find the name of elements in array 'intersted_by' using command??
You can have the size of your result in the mongo shell using :
db.collection.count()
Replace collection by the name of your collection. You can also add a find condition like this :
db.collection.find().count()
Like that, you wan restrict your result with deffernts clauses before count the numbers of data corresponding
Edit : don't forget to do the command use databaseName
if you're not in your database, it does'nt work
You can count the amount of keys by doing:
var count = Object.keys(myObject).length;

MongoDB - Need help updating an Object within an Array of a Document

Situation:
I have a collection named 'employees'. This collection contains an array of managers. Each manager object has a property called 'directReports'. This property is an array of objects representing their subordinates. For example:
db.employees.find({ name: 'John Smith' });
{
"id" : 1234,
"name" : "John Smith",
"FirstName" : "John",
"LastName" : "Smith",
"SamAccountName" : "jsmith",
"DepartmentName" : "Management",
"SupID" : 0,
"Email" : "jsmith#company.tld",
"SupSamAccountName" : "bross",
"SupName" : "Bob Ross",
"directReports" : [
{
"id" : 5678,
"name" : "Jane Doe",
"FirstName" : "Jane",
"LastName" : "Doe",
"SamAccountName" : "jdoe",
"DepartmentName" : "Agent",
"SupID" : 1234,
"Email" : "jdoe#company.tld",
"SupSamAccountName" : "jsmith",
"SupName" : "John Smith",
},...]}
What I'd Like to Do:
I'd like to add a new property called 'status' (with a value of 'Lunch') to Jane Doe.
How can I do this?
Any help is extremely appreciated!
Assuming SamAccountNames are unique:
db.employees.update({
{ SamAccountName: "jsmith", directReports.SamAccountName: "jdoe" },
{ $set: { directReports.$.status: "Lunch" } }
})
Based on this question's tags, since you're using Mongoose, be sure to update your schema appropriately. You might consider reworking your schema to take advantage of Mongoose query population.
I think you need to add 'status' with the value of 'launch' to your model and after create a function to update all the employees data.
Hope it helps

Resources