Is it possible to create relationship with data in array Laravel + MongoDB - php

I have a collection with Data1 like
{
_id : "1",
total_amount : 5876,
date: "20-Jun-2018"
},
{
_id : "2",
total_amount : 5776,
date: "20-Jun-2018"
}
I want to store these data in another collection Data2 as follows :
{
name : "XYZ",
adjustments : [
{
data1_id : "1",
adjust_amount : 675
},
{
data1_id : "2",
adjust_amount : 6785
}
]
}
Storing this data isn't a problem in an array of Objects form. But is there any way I can create a relationship with the data within the array adjustments?
At the time of listing, I want adjustments with adjust_amount and all the related data.

Related

How to search multiple collections in mongoDB [duplicate]

This question already has answers here:
How to Match on Joined Collections Using Laravel and MongoDB?
(1 answer)
How to join to two additional collections with conditions
(1 answer)
Aggregate $lookup Total size of documents in matching pipeline exceeds maximum document size
(2 answers)
Closed 4 years ago.
I have 2 collections in mongoDB namely product and author . Now the product collection has an object called the detail which has the title and other details whereas the author table has details regarding the author . Now i am trying to make a search that finds both title and author .. For eg: if the title is matched the details of that product should be listed and if the author is matched then again the details of that product should be shown. The author_id is a foreign_key in the product collection and the _id is a primary key in the author collection.
Below is my collection
The Product Collection
{
"_id" : ObjectId("5af2bd44a003533a8abf4e56"),
"product_type_id" : "5ae834807ae0d9538e45ab45",
"date_added" : "2018-03-12 12-3-54",
"status" : 1,
"detail" : {
"title" : "The random title",
"author_id" : "5af2c401a003533a8abf4e57",
"test_id" : 12345,
"description" : "I have a mongoDB collection with f rows",
"mrp" : 200,
"binding" : "sd",
"language" : "English",
"isbn" : NumberLong("9788700631625"),
"isbn_10" : 747532745,
"ean" : 897655,
"pages" : 200
}
}
This is the author collection
{
"_id" : ObjectId("5af2c401a003533a8abf4e57"),
"name" : "Dan Brown",
"test_id" : 12345
}
So far i have to search on the collections independently . But not together
For author search
db.author.aggregate
([{
"$match":
{
"name":"Dan Brown"
}
},
{
"$lookup":
{
"from": "product",
"localField": "test_id",
"foreignField": "detail.test_id",
"as": "users"
}
}
]
).pretty();
And title has been accessed using the normal find() method
EDIT 1:
So this is what i have tried so far. Is this the right approach . Btw it's still not working though
db.product.aggregate
(
[
{
"$match":
{
detail.title : 'The random title'
}
},
{
"$lookup":
{
"from": "author",
"localField": "test_id",
"foreignField": "detail.test_id",
"as": "tb2"
}
},
{
"$unwind": "$tb2"
},
{
"$match":
{
"tb2.name": "agent"
}
}
]
);

How to decode data of multiple rows in json and display in php tables using primary key date

date ,
details {
"target1" : "test1",
"count1" : "3",
"remarks1" : "done",
"target2" : "test2",
"count2" : "3",
"remarks2" : "done",
"target3" : "test3",
"count3" : "3",
"remarks3" : "running"
}
Where date(pk) and details are two fields of a table. Display rows in tables of particular date.
I dont really know what "php tables" are. But you probably need the functions json_decode() and array_merge().
For each row fetched from DB:
$table[] = array_merge($row['id'], json_decode('details'))

Mongo and Yii -> update with $set a field in all the arrays of a subdocument

I'm having problems updating a specific field in all the arrays of a subdocument. I have the following structure in MongoDB:
{
"_id" : ObjectId("539c9e97cac5852a1b880397"),
"DocumentoDesgloseER" : [
{
"elemento" : "COSTO VENTA",
"id_rubroer" : "11",
"id_documento" : "45087",
"abreviatura" : "CV",
"orden" : "1",
"formula" : "Cuenta Contable",
"tipo_fila" : "1",
"color" : "#FFD2E9",
"sucursal" : "D",
"documentoID" : "0",
"TOTAL" : "55426.62",
},
{ ... MORE OF THE SAME ... }
],
"id_division" : "2",
"id_empresa" : "9",
"id_sucursal" : "37",
"ejercicio" : "2008",
"lastMonthNumber" : NumberLong(6),
}
I need to update the field "documentoID" to a specific value; like "20" for example, in all the arrays of the subdocument "DocumentoDesgloseER". How I can do this?
I tried the following (with $ operator) and is not working:
$querySearch = array('id_division'=>'2', 'id_empresa'=>'9', 'id_sucursal'=>'37', 'ejercicio'=>'2008');
$queryUpdate = array('$set'=>array('DocumentoDesgloseER.$.documentoID'=>'20'));
Yii::app()->edmsMongoCollection('DocumentosDesgloseER')->update($querySearch,$queryUpdate);
By the way, I'm using Yii Framework to make the connection with Mongo. Any help or advice is welcome.
Thanks ;D!
Unfortunately, you can't currently use a positional operator to update all items in an array. There is a ticket opened in the MongoDB JIRA about this issue.
There a two "solutions":
Change your schema so that your embedded documents are in the separate collection (it's probably not what you want).
The best you can do, if you don't want to change your schema, is to update each subdocument in PHP and then save the whole document.

MongoDB Query to find out all the array elements of a collection

I have a pretty big MongoDB document that holds all kinds of data. I need to identify the fields that are of type array in a collection so I can remove them from the displayed fields in the grid that I will populate.
My method now consists of retrieving all the field names in the collection with
This was taken from the response posted here MongoDB Get names of all keys in collection
mr = db.runCommand({
"mapreduce" : "Product",
"map" : function() {
for (var key in this) { emit(key, null); }
},
"reduce" : function(key, stuff) { return null; },
"out": "things" + "_keys"
})
db[mr.result].distinct("_id")
And running for each of the fields a query like this one
db.Product.find( { $where : "Array.isArray(this.Orders)" } ).count()
If there's anything retrieved the field is considered an array.
I don't like that I need to run n+2 queries ( n being the number of different fields in my collection ) and I wouldn't like to hardcode the fields in the model. It would defeat the whole purpose of using MongoDB.
Is there a better method of doing this ?
I made a couple of slight modifications to the code you provided above:
mr = db.runCommand({
"mapreduce" : "Product",
"map" : function() {
for (var key in this) {
if (Array.isArray(this[key])) {
emit(key, 1);
} else {
emit(key, 0);
}
}
},
"reduce" : function(key, stuff) { return Array.sum(stuff); },
"out": "Product" + "_keys"
})
Now, the mapper will emit a 1 for keys that contain arrays, and a 0 for any that do not. The reducer will sum these up, so that when you check your end result:
db[mr.result].find()
You will see your field names with the number of documents in which they contain Array values (and a 0 for any that are never arrays).
So this should give you which fields contain Array types with just the map-reduce job.
--
Just to see it with some data:
db.Product.insert({"a":[1,2,3], "c":[1,2]})
db.Product.insert({"a":1, "b":2})
db.Product.insert({"a":1, "c":[2,3]})
(now run the "mr =" code above)
db[mr.result].find()
{ "_id" : "_id", "value" : 0 }
{ "_id" : "a", "value" : 1 }
{ "_id" : "b", "value" : 0 }
{ "_id" : "c", "value" : 2 }

Duplicate value inserted in the mongodb "_id" field

In mongodb, We can assign our own value to _id field and the "_id" field value may be of any type, other than arrays, so long as it is a unique -- From the docs.
But in my live database, i can see some records were duplicated as follows,
db.memberrecords.find().limit(2).forEach(printjson)
{
"_id" : "999783",
"Memberid" : "999783",
"Name" : "ASHEESH SHARMA",
"Gender" : "M",
}
{
"_id" : "999783",
"Memberid" : "999783",
"Name" : "Sanwal Singh Meena",
"Gender" : "M",
}
In above records, the same _id value inserted twice in the table. When i tested with local database it is not allowing to insert the same _id record and throwing error as follows,
E11000 duplicate key error index: mongoms.memberrecords.$_id_ dup key: { : "999783" }
Below is the Indexes for my live memberrecords table(for your reference),
db.memberrecords.getIndexes()
[
{
"name" : "_id_",
"ns" : "mongoms.memberrecords",
"key" : {
"_id" : 1
},
"v" : 0
},
{
"_id" : ObjectId("4f0bcdf2b1513267f4ac227c"),
"ns" : "mongoms.memberrecords",
"key" : {
"Memberid" : 1
},
"name" : "Memberid_1",
"unique" : true,
"v" : 0
}
]
Note: i have two sharding for this table.
Any suggestion on this please,
Is your shard key the _id field? You can only have one unique index enforced across a cluster: the shard key (otherwise the server would have to check with every shard on every insert).
So: on a single a shard, _id will be unique. However, if it isn't your shard key, all bets are off across multiple shards.
See http://www.mongodb.org/display/DOCS/Sharding+Limits#ShardingLimits-UniqueIndexesDOCS%3AIndexes%23UniqueIndexes.

Categories