Get index of array item if item of array equals name - arrays

I have an array of items like this:
{
"dateAdded" : "2016-02-09 12:41:37",
"customValue" : "5",
"name" : "highestHeight"
},
{
"dateAdded" : "2016-02-09 12:41:37",
"customValue" : "46.91",
"name" : "highestWeight"
},
{
"dateAdded" : "2016-02-09 12:41:37",
"customValue" : "14972.02",
"name" : "highestScore"
},
I would like to get the items associated with the item that has the name = highestScore but not sure how or even what I should be searching for to find an example.

How about starting with the documentation on Array, which will show that it implements the CollectionType protocol, which has a filter function:
myArray.filter({ $0.name == "highestScore" })
That assumes it is an array of objects/types, and not an array of Dictionary instances. If that was the case, then you would use:
myArray.filter({ $0["name"] == "highestScore" })

You can look at functional filtering here: http://www.raywenderlich.com/82599/swift-functional-programming-tutorial
Do something like:
highscoreArray= yourArray.filter { (dictionary) in dictionary["name"]! == "highestScore" }
Haven't tested it but it should be along of the lines of that.

Related

MongoDB: Check for missing documents using a model tree structures with an array of ancestors

I'm using a model tree structures with an array of ancestors and I need to check if any document is missing.
{
"_id" : "GbxvxMdQ9rv8p6b8M",
"type" : "article",
"ancestors" : [ ]
}
{
"_id" : "mtmTBW8nA4YoCevf4",
"parent" : "GbxvxMdQ9rv8p6b8M",
"ancestors" : [
"GbxvxMdQ9rv8p6b8M"
]
}
{
"_id" : "J5Dg4fB5Kmdbi8mwj",
"parent" : "mtmTBW8nA4YoCevf4",
"ancestors" : [
"GbxvxMdQ9rv8p6b8M",
"mtmTBW8nA4YoCevf4"
]
}
{
"_id" : "tYmH8fQeTLpe4wxi7",
"refType" : "reference",
"parent" : "J5Dg4fB5Kmdbi8mwj",
"ancestors" : [
"GbxvxMdQ9rv8p6b8M",
"mtmTBW8nA4YoCevf4",
"J5Dg4fB5Kmdbi8mwj"
]
}
My attempt would be to check each ancestors id if it is existing. If this fails, this document is missing and the data structure is corrupted.
let ancestors;
Collection.find().forEach(r => {
if (r.ancestors) {
r.ancestors.forEach(a => {
if (!Collection.findOne(a))
missing.push(r._id);
});
}
});
But doing it like this will need MANY db calls. Is it possible to optimize this?
Maybe I could get an array with all unique ancestor ids first and check if these documents are existing within one db call??
First take out all distinct ancesstors from your collections.
var allAncesstorIds = db.<collectionName>.distinct("ancestors");
Then check if any of the ancesstor IDs are not in the collection.
var cursor = db.<collectionName>.find({_id : {$nin : allAncesstorIds}}, {_id : 1})
Iterate the cursor and insert all missing docs in a collection.
cursor.forEach(function (missingDocId) {
db.missing.insert(missingDocId);
});

Add data to array within array in MongoDB

So heres my mongodb document:
{
"_id" : "",
"lists" : [
{
"name" : "list 1",
"items" : []
},
{
"name" : "list 2",
"items" : []
}
]
}
How would I go about adding an object inside "items"?
This is the code I have so far, but it doesn't work:
xxx.update(_id, {$push: { "lists.$.items": item}});
Note that I have access to the index (variable called 'index'), so its possible to insert an item at index, 0, 1, 2..., etc.
I tried this before, but it won't work:
xxx.update({_id, "lists": index}, {$push: { "lists.$.items": item}});
I also looked at other similar questions and couldn't find anything. Most of them have some sort of id field in their arrays, but I don't.
What about
xxx.update({_id}, {$push: { "lists.index.items": item}});
Of course this would fail, what I mean is replace index with real index values
xxx.update({_id}, {$push: { "lists.2.items": item}});
You can manipulate the update json based on the index maybe as below.
var update = '{$push: { "lists.'+index+'.items": '+item+'}}';
var updateObj = JSON.parse(update);
xxx.update({_id}, updateObj);
Not sure if it will work as it is or it would need further tweaking, but you get the idea.

Is there a better way to iterate over this JSON data structure?

This is the data structure in question:
"EditedArticles" : {
"a3" : {
"versions" : [ {
"moment" : "a3",
"question" : "a3",
"situation" : "a3",
"version" : 1
}, ...
]
}
}
Currently, I am using three for loops to access the properties in EditedArticles.a3.versions
var getArticlesByMoment = function (moment,situation) {
angular.forEach(items, function(article, value) {//items are a1,a2,a3...
angular.forEach(article, function(versions, value) {//versions is the array containing version for each article
var checkfirst=0;
angular.forEach(versions, function(version, value) {//version is the version of an article
checkfirst++;
if (checkfirst == 1 && version.moment == moment && version.situation == situation) {
//do something;
return;
}
})
})
})
}
I want to access the properties inside the versions array for each item (eg. a3) to check if an item has the same moment/situation as a desired one. If there are a lot of items, a1 - a1000, then I think this will take a long running time. There may be many objects in each versions array but I only need to check the first object for a matching moment and situation as the rest of the objects will share the same values for those two properties.
Is there a better/faster way to access these properties? I am using an http GET call to get all the items (eg. a3) in EditedArticles.json
Thank you
You could do this to traverse your json object recursivly:
function traverse(jsonObj) {
if( typeof jsonObj == "object" ) {
$.each(jsonObj, function(k,v) {
// object or array
traverse(v);
});
}
else {
// actual value
}
}

MongoDB remove an item from an array inside an array of objects

I have a document that looks like this:
{
"_id" : ObjectId("56fea43a571332cc97e06d9c"),
"sections" : [
{
"_id" : ObjectId("56fea43a571332cc97e06d9e"),
"registered" : [
"123",
"e3d65a4e-2552-4995-ac5a-3c5180258d87"
]
}
]
}
I'd like to remove the 'e3d65a4e-2552-4995-ac5a-3c5180258d87' in the registered array of only the specific section with the _id of '56fea43a571332cc97e06d9e'.
My current attempt is something like this, but it just returns the original document unmodified.
db.test.findOneAndUpdate(
{
$and: [
{'sections._id': ObjectId('56fea43a571332cc97e06d9e')},
{'sections.registered': 'e3d65a4e-2552-4995-ac5a-3c5180258d87'}
]
},
{
$pull: {
$and: [
{'sections._id': ObjectId('56fea43a571332cc97e06d9e')},
{'sections.registered': 'e3d65a4e-2552-4995-ac5a-3c5180258d87'}
]
}
})
I've looked in to $pull, but I can't seem to figure out how to make it work on an array of nested objects containing another array. The $pull examples all seem to deal with only one level of nesting. How do I remove the matching entry from the registered array of the item in the sections array with the _id that I supply?
You need to use the positional $ update operator to remove the element from your array. You need this is because "sections" is an array of sub-documents.
db.test.findOneAndUpdate(
{ "sections._id" : ObjectId("56fea43a571332cc97e06d9e") },
{ "$pull": { "sections.$.registered": "e3d65a4e-2552-4995-ac5a-3c5180258d87" } }
)

Mongodb How to delete/clear an array in an other array

I would like to now how you can delete/clear an entire array that is inside another array.
This is how my data looks like. I would like to know how i can clear out the array "companyvote". Any suggestions?
{
"_id" : ObjectId("55529cbb056565e80d963fac"),
"email" : "test#test.be",
"img" : "\img\1920x12001431477435530.jpg",
"companyvote" : [
"Lovely inc",
"Behond imagination"
],
"__v" : 0
}
You can use $unset to remove the property like this
db.companies.update({ "_id" : ObjectId("55529cbb056565e80d963fac")},
{$unset:{'companyvote':1}});
Or if you just want to clear the content of the array you can use $set
db.companies.update({ "_id" : ObjectId("55529cbb056565e80d963fac")}, {$set:{'companyvote':[]}})
To delete contents for all record, you just need to remove the filter by Id
db.companies.update({}, {$set:{'companyvote':[]}})
This is what really worked for me.
socket.on('deleteAllVotes', function() {
Slides.find().exec(function(err, b) {
for(var i = 0; i < b.length; i++) {
var allslides = b[i].companyvote;
Slides.update({companyvote:allslides}, {$set:{'companyvote':[]}},function(err, b) {});
}
});
socket.emit('deleteAllVotes');
});
You can clear the content of array for one record with
db.companies.update({ _id : ObjectId("55529cbb056565e80d963fac")}, {$set:{'companyvote':[]}});
or
db.companies.update({ "_id" : ObjectId("55529cbb056565e80d963fac")}, {$unset:{'companyvote':1}});
If you want to clear multi record, don't forget to add option
db.companies.update({}, {$set:{'companyvote':[]}}, {multi: true});
or
db.companies.update({}, {$unset:{'companyvote':1}}, {multi: true});

Resources