Updating nested Array elements in mongodb without reputations - arrays

i have collection called 'test' in that there is a document like:
{
"_id" : 1
"letters" : [
[ "A", "B" ],
[ "C", "D" ],
[ "A", "E", "B", "F" ]
]
}
if i updated the document by using $addToSet like this:
db.getCollection('test').update({"_id" : 1}, {$addToSet:{"letters": ["A", "B"] }})
it will not inserted another value. still the document look like
{
"_id" : 1
"letters" : [
[ "A", "B" ],
[ "C", "D" ],
[ "A", "E", "B", "F" ]
]
}
if im updating like this:
db.getCollection('test').update({"_id" : 1}, {$addToSet:{"letters": ["B", "A"] }})
Now it will update the document like:
{
"_id" : 1
"letters" : [
[ "A", "B" ],
[ "C", "D" ],
[ "A", "E", "B", "F" ],
[ "B", "A" ]
]
}
my requirment is if im give like this also (["B", "A"]), it will not update that document. Because the same letters are already present in the array.
could anyone can please give the solution.

#Shubham has the right answer. You should always sort your letters before saving into the document. So your original document should have been (I changed the third array):
{
"_id" : 1,
"letters" : [
[ "A", "B" ],
[ "C", "D" ],
[ "A", "B", "C", "F" ]
]
}
Then in your application do the sort. I'm including a Mongo Shell example here.
var input = ["B", "A"];
input.sort();
db.getCollection('test').update({"_id" : 1}, {$addToSet:{"letters": input}});

Try this answer , it works.
Use $push to insert any item in the array in your case.
db.getCollection('stack').update(
{ _id: 1 },
{ $push: { "letters": ["B", "A"] } }
)
For reference about $push you can view this link -
https://docs.mongodb.com/manual/reference/operator/update/push/

Related

mongodb using $in for matching array with array inside aggregate

I am trying to perform an aggregate query in MongoDB. My target is to check if any values within an array exists in another array and conditionally introduce a third variable accordingly.
For example, I have an array A => ["a", "b"] and another array B => ["a", "c", "d"]
So in this case as "a" exists in both A & B, they should match.
aggregate.push({
"$addFields": {
"canClaim": {
$cond: [{
$in: [["a", "b"], ["a", "c", "d"]]
}, 1, 0]
}
}
})
Does this help you?
db.collection.aggregate({
"$addFields": {
"c": {
"$setIntersection": [
"$a",
"$b"
]
}
}
},
{
"$match": {
"c.1": {
"$exists": true
}
}
})
Mongo Playground

Get an array of values of a field in MongoDB

I have some entries like:
{ "name":"a", "value":10 }
{ "name":"b", "value":20 }
{ "name":"c", "value":10 }
...
And I can select names from a query with db.collection.find({"value":10},{"name":1, _id: false}). It gives me the following:
{ "name" : "a" }
{ "name" : "c" }
...
However, I want it to return an array of values, not a set of { key : value } pairs. (like [ "a", "c", ... ]). Is there a way to achieve this with only MongoDB queries or should I select and put them in an array in my application?
Current Output:
{ "name" : "a" }
{ "name" : "c" }
...
Expected output:
["a", "c", ...]
If the above is not a possible output, it may be also
{ "result": ["a", "c", ...] }
db.collection.distinct( "name", { "value": 10 })
from #Sagar Reddy comment will return a set array:
["a", "c"]
This is probably what you need. Aniway, a similar more complex query can be achieved using aggregation, where you can use extra aggregation stages.
db.collection.aggregate([
{ $match: { value: 10 }},
{ $group: { _id: null, result: { $addToSet: '$name' }}},
{ $project: { _id: 0, result: 1 }}
])
In the group stage, addToSet can be replaced with push if you want the same value to appear multiple times.
Output using addToSet:
{ "result" : [ "c", "a" ] }
Ex output using push:
{ "result" : [ "a", "c", "c" ] }

How to query for elements which contains given string in array of strings in MongoDB (with Mongoose)

This is my User schema:
var UserSchema = new Schema({
name:String,
groups: [String]
});
I want to get array of names of all users who are in x group.
For example data set:
[
{
"name":"a",
"groups":[
"1",
"2"
]
},
{
"name":"b",
"groups":[
"3x",
"4"
]
},
{
"name":"c",
"groups":[
"1",
"4"
]
},
{
"name":"d",
"groups":[
"2",
"3"
]
},
{
"name":"e",
"groups":[
]
}
]
I need results:
for group 1:
["a","c"]
for group 2:
["a","d"]
for group 3:
["b","d"]
for group 4:
["c"]
for group 5:
[]
Is it possible to write query like this? How to do it?
It is quiet simple, Just requires an aggregate operation with two stages.
$unwind by the groups field.
$group by the groups field
Code:
db.t.aggregate([
{$unwind:"$groups"},
{$group:{"_id":"$groups","names":{$addToSet:"$name"}}}
])
Sample Result:
{ "_id" : "3x", "names" : [ "b" ] }
{ "_id" : "4", "names" : [ "c", "b" ] }
{ "_id" : "2", "names" : [ "d", "a" ] }
{ "_id" : "3", "names" : [ "d" ] }
{ "_id" : "1", "names" : [ "c", "a" ] }

MongoDB: deleting duplicate documents with arrays

I'm trying to remove all duplicates in a collection with ensureIndex and dropDups, but this method doesn't seem to work with arrays.
For example, if I have a collection that looks like this:
{ "_id" : ObjectId("54d8f889e3fdfe0cd8b769ed"), "field1" : "a", "field2" : [ "a", "b" ] }
{ "_id" : ObjectId("54d8f89be3fdfe0cd8b769ee"), "field1" : "a", "field2" : [ "a", "b" ] }
{ "_id" : ObjectId("54d8f8a3e3fdfe0cd8b769ef"), "field1" : "a", "field2" : [ "a", "c" ] }
{ "_id" : ObjectId("54d8f8abe3fdfe0cd8b769f0"), "field1" : "a", "field2" : [ "b", "a" ] }
{ "_id" : ObjectId("54d8f8c5e3fdfe0cd8b769f1"), "field1" : "b", "field2" : [ "a", "b" ] }
and use ensureIndex like this:
> db.test.ensureIndex({field1: 1, field2: 1}, {unique: true, dropDups: true})
the result would be:
> db.test.find()
{ "_id" : ObjectId("54d8f89be3fdfe0cd8b769ee"), "field1" : "a", "field2" : [ "a", "b" ] }
{ "_id" : ObjectId("54d8f8c5e3fdfe0cd8b769f1"), "field1" : "b", "field2" : [ "a", "b" ] }
Is there a way to do this so that only exact Duplicates (in my example collection only the first or second entry) get deleted?
As I know this feature doesn't work in arrays. Any particular reason why you can't just use $addToSet when you insert the data?
Check this question, maybe help you MongoDB: Unique index on array element's property

Store multiple values in single key in json

I need to store many values in single key of json. e.g.
{
"number" : "1","2","3",
"alphabet" : "a", "b", "c"
}
Something like this. Any pointers?
Use arrays:
{
"number": ["1", "2", "3"],
"alphabet": ["a", "b", "c"]
}
You can the access the different values from their position in the array. Counting starts at left of array at 0. myJsonObject["number"][0] == 1 or myJsonObject["alphabet"][2] == 'c'
{
"number" : ["1","2","3"],
"alphabet" : ["a", "b", "c"]
}
{
"success": true,
"data": {
"BLR": {
"origin": "JAI",
"destination": "BLR",
"price": 127,
"transfers": 0,
"airline": "LB",
"flight_number": 655,
"departure_at": "2017-06-03T18:20:00Z",
"return_at": "2017-06-07T08:30:00Z",
"expires_at": "2017-03-05T08:40:31Z"
}
}
};

Resources