I want to delete information from a document but the code runs and no error occurs.But it doesn't delete the record.
I haave data like that
{
"id": "12345",
"info": [
{
"sno":1
"name": "XYZ",
"email": "xyz#example.com"
},
{
"sno":2
"name": "XYZ",
"email": "xyz#example.com"
}
]
}
and I want to delete data where id=12345 and info.sno=2
my php code id
<?
$m=new Mongo();
$db=$m->database;
$cond=array("id"=>'12345');
$data=array('$pull'=>array("info.sno"=>2));
//I used before this $data=array('$pull'=>array("info"=>array("sno"=>2)));
echo json_encode($data);
$db->info->update($cond,$data);
$st=$db->Command(array("getlasterror"=>1));
?>
I run mongo db command like:
db.info.update({"id":12345},{'$pull':{"info":{"sno":2}}});
Your commented out line is correct:
test> db.foo.findOne()
{
"_id" : ObjectId("4f74737cc3a51043d26f4b90"),
"id" : "12345",
"info" : [
{
"sno" : 1,
"name" : "XYZ",
"email" : "xyz#example.com"
},
{
"sno" : 2,
"name" : "XYZ",
"email" : "xyz#example.com"
}
]
}
test> db.foo.update({"id":"12345"}, {"$pull":{info:{sno:2}}})
test> db.foo.findOne()
{
"_id" : ObjectId("4f74737cc3a51043d26f4b90"),
"id" : "12345",
"info" : [
{
"sno" : 1,
"name" : "XYZ",
"email" : "xyz#example.com"
}
]
}
Related
I'm using mongoDb in my project, and I have problem using lookup on embedded data.. I searched for my problem and read similar codes.. but they didn't help my problem..
I mean in my embed document there is a variable named user that I want to load its data by lookup..
this is how my documents is:
"_id" : ObjectId("5d0f6a993702da22bc00474d"),
"quotes" : [
{
"amount" : NumberInt(100),
"user" : {
"_id" : ObjectId("5cc69f7f46ab4cedda5c3c12")
},
"details" : "some quote details",
"_id" : ObjectId("5d0f6a993702da22bc00474c"),
"status" : "a"
},
{
"amount" : NumberInt(120),
"user" : {
"_id" : ObjectId("5cc69kij46ab4cedda5c3c12")
},
"details" : "some quote details 2",
"_id" : ObjectId("5d0f6a993702da22bc00484k"),
"status" : "a"
}
],
"status" : "Approved",
"title" : "gardening",
"created_at" : NumberInt(1560841417)
so I want my output be like this:
"_id" : ObjectId("5d0f6a993702da22bc00474d"),
"quotes" : [
{
"amount" : NumberInt(100),
"user" : {
"_id" : ObjectId("5cc69f7f46ab4cedda5c3c12"),
"firstName": "John",
"lastNAme": "Doe",
"phone": 514298742
},
"details" : "some quote details",
"_id" : ObjectId("5d0f6a993702da22bc00474c"),
"status" : "a"
},
{
"amount" : NumberInt(120),
"user" : {
"_id" : ObjectId("5cc69kij46ab4cedda5c3c12")
"firstName": "Jane",
"lastNAme": "Doe",
"phone": 5148547642
},
"details" : "some quote details 2",
"_id" : ObjectId("5d0f6a993702da22bc00484k"),
"status" : "a"
}
],
"status" : "Approved",
"title" : "gardening",
"created_at" : NumberInt(1560841417)
I found the solution.. this worked for me..
.aggregate([
{
{
"$unwind": {
"path": "$quotes",
"preserveNullAndEmptyArrays": true
}
},
{
"$lookup": {
"from": "users",
"localField": "quotes.user._id",
"foreignField": "_id",
"as": "quotes.user",
}
},
{
"$unwind": {
"path": "$quotes.user",
"preserveNullAndEmptyArrays": true
}
},
{
"$group": {
"_id": null,
"quotes": {"$push": "$quotes"},
"status": {"$first": "$status"},
"title": {"$first": "$title"},
"created_at": {"$first": "$created_at"},
}
},
}
])
I posted my answer if anyone have the same issue.
I have below scenario where, I have one collection "demo" having all data which need to be search,
I have used text search,
{
"_id" : "1",
"type" : "Deal",
"description_title" : "New Deal for test",
"images" : "",
"start_date" : ISODate("2017-07-20T00:00:00.000+0000"),
"end_date" : ISODate("2017-10-30T11:59:00.000+0000"),
"status" : "1"
}
{
"_id" : "2",
"type" : "Event",
"description_title" : "Event1 test",
"images" : "",
"end_date" : ISODate("2017-10-20T00:00:00.000+0000")
"status" : "1"
}
{
"_id" : "3",
"type" : "Text",
"description_title" : "test",
"images" : "",
"status" : "1"
}
{
"_id" : "4",
"type" : "Event",
"description_title" : "Event2 test",
"images" : "",
"end_date" : ISODate("2017-07-20T00:00:00.000+0000")
"status" : "1"
}
In above collection I have stored all data which need to be search by using text search, But when "type" : "Event"/"Deal" then it should only return Active Deals & Events "Current date is less than end_date" need to be searched.
In above collection When I search for "Test", It should return,
{
"_id" : "1",
"type" : "Deal",
"description_title" : "New Deal for test",
"images" : "",
"start_date" : ISODate("2017-07-20T00:00:00.000+0000"),
"end_date" : ISODate("2017-10-30T11:59:00.000+0000"),
"status" : "1"
}
{
"_id" : "2",
"type" : "Event",
"description_title" : "Event1 test",
"images" : "",
"end_date" : ISODate("2017-10-20T00:00:00.000+0000")
"status" : "1"
}
{
"_id" : "3",
"type" : "Text",
"description_title" : "test",
"images" : "",
"status" : "1"
}
I have used below query, but it gives me all result,
db.demo.find({'$text' : {'$search' => 'test'},'$or' : {
{"type" : "Deal","end_date" : {'$gte' : ISODate("2017-09-14T11:59:00.000+0000") }},
{"type" : "Text"},
{"type" : "Event","end_date" : {'$gte' : ISODate("2017-09-14T11:59:00.000+0000") }},
}})
Above query return all records.
Please help me to achieve my result.
How to update members age whose name is TEST1 using yii2.?
Used below code to update , but i am specifying the indexes there , i want with out specifying the indexes.
User::updateAll([ '$set'=> ['Addresses.0.members.0.age'=>100] ],['IN','Addresses.members.name',['TEST1'] ]);
{
"_id" : ObjectId("595209b65312f48195fb2e01"),
"username" : "Test name",
"Addresses" : [
{
"address_no" : 1,
"Address" : "Test house",
"City" : "test city",
"State" : "Test state",
"Mobile" : "9999999",
"members" : [
{
"name" : "TEST1",
"age" : 35
},
{
"name" : "TEST2",
"age" : 30
},
]
},
{
"address_no" : 2,
"Address" : "2B, Test place",
"City" : "Test city",
"State" : "Test State",
"Pincode" : "12345",
"Phone" : "1234568789",
"Mobile" : 9999999999
}
],
"Beneficiaries" : [
{
"beneficiary_id" : 1,
"Name" : "Test1",
"Age" : "28",
"Sex" : "F"
}
],
"auth_key" : "esd8d89ds89ds89ds89ds",
}
there is position operator $ to do this kind of job
{
"Addresses.members.name" : "TEST2",
},
{
$set: {
"Addresses.$.members.0.age" : 40
}
}
Here I specified first index as it supports up to one level depth.
New feature might release in future to resolve this issue: https://jira.mongodb.org/browse/SERVER-831
Yii::$app->mongodb->getCollection('user')->update(['_id' => $id, 'members.name' => 'Test1'], ['$set' => [
'members.$.age' => 100,
]]);
Can't seem to find an answer to my doubt, so I decided to post the question and see if someone can help me.
In my application, I have an array of ids which comes from the backend and which is ordered already as I want, for example:
[0] => 23, [1] => 12, [2] => 45, [3] => 21
I then "ask" elasticsearch the information corresponding to each id present in this array, using a terms filter. The problem is the results don't come in the order of the ids I sent, so the results get mixed up, like: [0] => 21, [1] => 45, [2] => 23, [3] => 12
Note that I can't sort in elasticsearch by the sorting that orders the array in the backend.
I also can't order them in php as I'm retrieving paginated results from elasticsearch, so if each oage had 2 results, elasticsearch could give me the info only for [0] => 21, [1] => 45, so I can't even order them with php.
How can I get the results ordered by the input array? Any ideas?
Thanks in advance
Here is one way you can do it, with custom scripted scoring.
First I created some dummy data:
curl -XPUT "http://localhost:9200/test_index"
curl -XPOST "http://localhost:9200/test_index/_bulk " -d'
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 1 } }
{ "name" : "Document 1", "id" : 1 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 2 } }
{ "name" : "Document 2", "id" : 2 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 3 } }
{ "name" : "Document 3", "id" : 3 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 4 } }
{ "name" : "Document 4", "id" : 4 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 5 } }
{ "name" : "Document 5", "id" : 5 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 6 } }
{ "name" : "Document 6", "id" : 6 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 7 } }
{ "name" : "Document 7", "id" : 7 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 8 } }
{ "name" : "Document 8", "id" : 8 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 9 } }
{ "name" : "Document 9", "id" : 9 }
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 10 } }
{ "name" : "Document 10", "id" : 10 }
'
I used an "id" field even though it's redundant, since the "_id" field gets converted to a string, and the scripting is easier with integers.
You can get back a specific set of docs by id with the ids filter:
curl -XPOST "http://localhost:9200/test_index/_search" -d'
{
"filter": {
"ids": {
"type": "docs",
"values": [ 1, 8, 2, 5 ]
}
}
}'
but these will not necessarily be in the order you want them. Using script based scoring, you can define your own ordering based on document ids.
Here I pass in a parameter that is a list of objects that relate ids to score. The scoring script simply loops through them until it finds the current document id and returns the predetermined score for that document (or 0 if it isn't listed).
curl -XPOST "http://localhost:9200/test_index/_search" -d'
{
"filter": {
"ids": {
"type": "docs",
"values": [ 1, 8, 2, 5 ]
}
},
"sort" : {
"_script" : {
"script" : "for(i:scoring) { if(doc[\"id\"].value == i.id) return i.score; } return 0;",
"type" : "number",
"params" : {
"scoring" : [
{ "id": 1, "score": 1 },
{ "id": 8, "score": 2 },
{ "id": 2, "score": 3 },
{ "id": 5, "score": 4 }
]
},
"order" : "asc"
}
}
}'
and the documents are returned in the proper order:
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"hits": {
"total": 4,
"max_score": null,
"hits": [
{
"_index": "test_index",
"_type": "docs",
"_id": "1",
"_score": null,
"_source": {
"name": "Document 1",
"id": 1
},
"sort": [
1
]
},
{
"_index": "test_index",
"_type": "docs",
"_id": "8",
"_score": null,
"_source": {
"name": "Document 8",
"id": 8
},
"sort": [
2
]
},
{
"_index": "test_index",
"_type": "docs",
"_id": "2",
"_score": null,
"_source": {
"name": "Document 2",
"id": 2
},
"sort": [
3
]
},
{
"_index": "test_index",
"_type": "docs",
"_id": "5",
"_score": null,
"_source": {
"name": "Document 5",
"id": 5
},
"sort": [
4
]
}
]
}
}
Here is a runnable example: http://sense.qbox.io/gist/01b28e5c038c785f0844abb7c01a71d69a32a2f4
How to search value in multidimensional array,
for example I want to search example keyword in the following data in mongodb
I used to fetch all data from command
>db.info.find()
{
"_id" : ObjectId("4f74737cc3a51043d26f4b90"),
"id" : "12345",
"info" : [
{
"sno" : 1,
"name" : "ABC",
"email" : "abc#example.com"
},
{
"sno" : 2,
"name" : "XYZ",
"email" : "xyz#example.com"
},
{
"sno" : 3,
"name" : "XYZ",
"email" : "xyz#demo.com"
},
{
"sno" : 4,
"name" : "ABC",
"email" : "abc#demo.com"
},
{
"sno" : 5,
"name" : "Rohan",
"email" : "rohan#example.com"
}
]
}
Now, to find data having example I used command
>db.info.find({"info.email":"example"})
and it gives
{
"_id" : ObjectId("4f74737cc3a51043d26f4b90"),
"id" : "12345",
"info" : [
{
"sno" : 1,
"name" : "ABC",
"email" : "abc#example.com"
},
{
"sno" : 2,
"name" : "XYZ",
"email" : "xyz#example.com"
},
{
"sno" : 3,
"name" : "XYZ",
"email" : "xyz#demo.com"
},
{
"sno" : 4,
"name" : "ABC",
"email" : "abc#demo.com"
},
{
"sno" : 5,
"name" : "Rohan",
"email" : "rohan#example.com"
}
]
}
But I want only 3 out of 5 sub rows like
{
"_id" : ObjectId("4f74737cc3a51043d26f4b90"),
"id" : "12345",
"info" : [
{
"sno" : 1,
"name" : "ABC",
"email" : "abc#example.com"
},
{
"sno" : 2,
"name" : "XYZ",
"email" : "xyz#example.com"
},
{
"sno" : 5,
"name" : "Rohan",
"email" : "rohan#example.com"
}
]
}
Rohan, MongoDB always returns the whole document that you are searching on. You can't just make it return the array elements in which your keyword was found. If you want to do that, then you need to make sure all all embedded documents in the "info" field are in their own collection. And that might mean that you need to link them back to the original document in your "info" collection. Perhaps something like:
{
"sno" : 1,
"name" : "ABC",
"email" : "abc#example.com"
"info_id" : "12345",
},
Alternatively, you can of course do post-processing in PHP to obtain only the rows that you want.
Perhaps this is a good idea?
http://php.net/manual/en/class.mongoregex.php
I tried Map Reduce Function and it works on this type of problems the code is something like that:
Write a map function
map=function ()
{
filter = [];
this.info.forEach(function (s) {if (/example/.test(s.email)) {filter.push(s);}});
emit(this._id, {info:filter});
}
Write a reduce function
reduce=function(key, values) { return values;}
MapReduce Function
res=db.info.mapReduce(map,reduce,{out:{inline:1}})
And The Output look likes:
"results" : [
{
"_id" : ObjectId("4f9a2de0ea4a65c3ab85a9d3"),
"value" : {
"info" : [
{
"sno" : 1,
"name" : "ABC",
"email" : "abc#example.com"
},
{
"sno" : 2,
"name" : "XYZ",
"email" : "xyz#example.com"
},
{
"sno" : 5,
"name" : "Rohan",
"email" : "rohan#example.com"
}
]
}
}
],
"timeMillis" : 1,
"counts" : {
"input" : 3,
"emit" : 3,
"reduce" : 0,
"output" : 3
},
"ok" : 1,
Now you can find your search data from
printjson(res.results)
Did you try $ (projection)?
db.info.find({"info.email":"example"}, {"info.email.$":1})
document