mongo find multiple array pairs - mongodb

If I have an array of pairs like so:
[
{foo: 'a', bar: 'b'},
{foo: 'b', bar: 'c'},
{foo: 'a', bar: 'd'},
{foo: 'b', bar: 'b'},
]
And I want to find documents in a collection that match any of these pairs exactly, how do I do this?
I've looked at the $in, $all, $elemMatch operators but none of them seem to quite do what I want.
I could do the queries individually:
db.baz.find({foo: 'a', bar: 'b'})
db.baz.find({foo: 'b', bar: 'c'})
db.baz.find({foo: 'a', bar: 'd'})
db.baz.find({foo: 'b', bar: 'b'})
But what I'd like to do is something like this:
db.baz.find([
{foo: 'a', bar: 'b'},
{foo: 'b', bar: 'c'},
{foo: 'a', bar: 'd'},
{foo: 'b', bar: 'b'},
]);

Try the $or syntax:
db.baz.find({
$or: [
{ foo: 'a', bar: 'b' },
{ foo: 'b', bar: 'c' },
{ foo: 'a', bar: 'd' },
{ foo: 'b', bar: 'b' },
]
})

Related

How to copy some elements from one Map into a new Map in Dart/Flutter?

How to copy some elements from one Map into a new Map in Dart/Flutter?
Old_Map = {
'A' : {Big : 'A', Small : 'a' },
'B' : {Big : 'B', Small : 'b' },
'C' : {Big : 'C', Small : 'c' },
'D' : {Big : 'D', Small : 'd' },
}
Old_Map => New_Map
I only want
'B' : {Big : 'B', Small : 'b' },
'C' : {Big : 'C', Small : 'c' },
you can do it like this
final oldMap = {
'A': {'Big': 'A', 'Small': 'a'},
'B': {'Big': 'B', 'Small': 'b'},
'C': {'Big': 'C', 'Small': 'c'},
'D': {'Big': 'D', 'Small': 'd'},
};
final newMap =
Map.fromIterable(oldMap.keys.where((k) => k == 'B' || k =='C'),
key: (k) => k, value: (v) => oldMap[v]);
as keys returns an Iterable<String> of your map keys, then you can check which key you want by using where method, then you can fill your values based on old map values.
final List<String> desiredKeys = ['B','C'];
final newMap = Map.from(oldMap);
newMap.removeWhere((String key, dynamic value) => !desiredKeys.contains(key));
First make a List containing your desired keys. Then by using removeWhere function remove those.

Dart: sort list of Strings by frequency

I'm trying to sort a list by frequency.
List myList = ["a", "b", "c", "d", "e", "f", "d", "d", "e"];
My expected output would be that the list is sorted on frequency & has no duplicated elements.
(myList has 3x "d" and 2x "e").
List output = ["d", "e", "a", "b", "c", "f"];
What's the most efficient way to do it?
Thanks in advance!
Is it also possible to do the same system with a List of Maps/Objects?
List myList2 = [{"letter": a, "info": myInfo}, {"letter": b, "info": myInfo}, ...]
It is not difficult to do that even without using package:collection.
List myList = ['a', 'b', 'c', 'd', 'e', 'f', 'd', 'd', 'e'];
// Put the number of letters in a map where the letters are the keys.
final map = <String, int>{};
for (final letter in myList) {
map[letter] = map.containsKey(letter) ? map[letter] + 1 : 1;
}
// Sort the list of the map keys by the map values.
final output = map.keys.toList(growable: false);
output.sort((k1, k2) => map[k2].compareTo(map[k1]));
print(output); // [d, e, a, b, c, f]
As for the second one, your desired output is unclear, but assuming that the values corresponding to the key letter are String and that you need exactly the same output as that of the first one, you can achieve it in a very similar way.
List myList2 = [
{'letter': 'a', 'info': 'myInfo'},
{'letter': 'b', 'info': 'myInfo'},
{'letter': 'c', 'info': 'myInfo'},
{'letter': 'd', 'info': 'myInfo'},
{'letter': 'e', 'info': 'myInfo'},
{'letter': 'f', 'info': 'myInfo'},
{'letter': 'd', 'info': 'myInfo'},
{'letter': 'd', 'info': 'myInfo'},
{'letter': 'e', 'info': 'myInfo'},
];
final map2 = <String, int>{};
for (final m in myList2) {
final letter = m['letter'];
map2[letter] = map2.containsKey(letter) ? map2[letter] + 1 : 1;
}
final output2 = map2.keys.toList(growable: false);
output2.sort((k1, k2) => map2[k2].compareTo(map2[k1]));
print(output2); // [d, e, a, b, c, f]

How does $max work over an array of objects?

Take an example collection with these documents:
client.test.foo.insert_one({
'name': 'clientA',
'locations': [
{'name': 'a', 'sales': 0, 'leads': 2},
{'name': 'b', 'sales': 5, 'leads': 1},
{'name': 'c', 'sales': 3.3, 'leads': 1}]})
client.test.foo.insert_one({
'name': 'clientB',
'locations': [
{'name': 'a', 'sales': 6, 'leads': 1},
{'name': 'b', 'sales': 6, 'leads': 3},
{'name': 'c', 'sales': 1.3, 'leads': 4}]})
How does $max determine which item in the location array is maximal?
client.test.foo.aggregate([{'$project': {'maxItem': {'$max': '$locations'}}}]))
Returns:
[{'_id': ObjectId('5b995d72eabb0f0d86dceda5'),
'maxItem': {'leads': 1, 'name': 'b', 'sales': 5}},
{'_id': ObjectId('5b995d72eabb0f0d86dceda6'),
'maxItem': {'leads': 3, 'name': 'b', 'sales': 6}}]
It looks like $max is picking to sort on sales but I am not sure why?
I discovered this
https://docs.mongodb.com/manual/reference/bson-type-comparison-order/#objects
which states:
MongoDB’s comparison of BSON objects uses the following order:
Recursively compare key-value pairs in the order that they appear
within the BSON object.
Compare the key field names.
If the key field names are equal, compare the field values.
If the field values are equal, compare the next key/value pair (return to step 1). An object without further pairs is less than an
object with further pairs.
which means that if sales is the first key in the bson object then I have my answer. I'm using pymongo and python dictionaries aren't ordered, so I switched to bson.son.SON and re-did the example:
client.test.foo.delete_many({})
client.test.foo.insert_one({
'name': 'clientA',
'locations': [
bson.son.SON([('name', 'a'), ('sales', 0), ('leads', 2)]),
bson.son.SON([('name', 'b'), ('sales', 5), ('leads', 1)]),
bson.son.SON([('name', 'c'), ('sales', 3.3), ('leads', 1)])]})
client.test.foo.insert_one({
'name': 'clientB',
'locations': [
bson.son.SON([('name', 'a'), ('sales', 6), ('leads', 1)]),
bson.son.SON([('name', 'b'), ('sales', 6), ('leads', 3)]),
bson.son.SON([('name', 'c'), ('sales', 1.3), ('leads', 4)])]})
And now its sorting by name:
client.test.foo.aggregate([{'$project': {'maxItem': {'$max': '$locations'}}}]))
Returns:
[{'_id': ObjectId('5b99619beabb0f0d86dcedaf'),
'maxItem': {'leads': 1, 'name': 'c', 'sales': 3.3}},
{'_id': ObjectId('5b99619beabb0f0d86dcedb0'),
'maxItem': {'leads': 4, 'name': 'c', 'sales': 1.3}}]

MongoDB select all fields that have values that are not in an array

I have the following scenario:
{
id: 1,
field_X: [a, b]
},
{
id: 2,
field_X: [c, d]
},
{
id: 3,
field_X: [d]
},
{
id: 4,
field_X: [a]
},
{
id: 5,
field_X: [a,b,c,f]
}
I want to find all fields that have any element from this array:
[a, b, c]
but do not have any other element; so the correct result will be:
{
id: 1,
field_X: [a, b]
},
{
id: 4,
field_X: [a]
}
How can I do this in MongoDB?
db.collection.find({ 'field_X': {'$in': [/[abc]/], '$nin': [/[^abc]/]} })
db_name.collection_name.find(({'field_X': {'$in': ['a', 'b', 'c'], '$nin': ['d', 'f']} })

How to create multiple reocrds of Ext.data.Model

I have this code:
Ext.define('mObject', {
extend: 'Ext.data.Model',
fields: [
{name: 'text', type: 'string'},
{name: 'x', type: 'int', convert: null},
{name: 'y', type: 'int', convert: null}
]
});
var obj = Ext.create('mObject', {
text : 'test test',
x : 100,
y : 24
});
How can I add more records? and is there any way to go to a specific record by a field value, I mean if I have 200 records and I ant to navigate to a record with name='yaya' do I have to go through all records and search for 'yaya' or there is alternative way?
Thank you all,
Ext.define('mObject', {
extend: 'Ext.data.Model',
fields: [
{name: 'text', type: 'string'},
{name: 'x', type: 'int', convert: null},
{name: 'y', type: 'int', convert: null}
]}
});
var mObject=Ext.create('Ext.data.Store', {
model: 'mObject',
data : []
});
mObject.add({text: 'sample1', x: 34, y:544});
mObject.add({text: 'sample2', x: 243, y:76});
mObject.add({text: 'sample3', x: 54, y:123});
mObject.add({text: 'sample4', x: 67, y:43});
mObject.add({text: 'sample5', x: 12, y:655});
var indx=mObject.find('text','sample4');
alert( mObject.getAt(indx).get('text'));