How can i update the ids field? - mongodb

Unfortunately, I cannot use positional operators since there is a bug that doesn't allow deeper than 1 embedded document: https://jira.mongodb.org/browse/SERVER-831
So this wont work (using the Mongodb Ruby driver):
stat_profile.update({ profile_id: profile.id, providers: { '$elemMatch' => { provider_name: 'foo', dates: { '$elemMatch' => { date: 20130911, relationships: { '$elemMatch' => { relationship_type: 'friend' } } } } } } },
{ '$set' => { 'providers.$.dates.$.relationships.$.ids' => [1,2,3] } })
Given the following collection. Relationships is embedded in dates, dates is embedded in providers.
How do I update the ids field?
{
"_id" => BSON::ObjectId('523048983858f61767000008'),
"profile_id" => 3,
"providers" => [
[0] {
"provider_name" => "foo",
"dates" => [
[0] {
"date" => 20130911,
"relationships" => [
[0] {
"relationship_type" => "acquaintance",
"count" => 0
},
[1] {
"relationship_type" => "friend",
"count" => 0,
"males_count" => 0,
"females_count" => 0,
"top_ten_countries" => [],
"ids" => []
}
]
}
]
}
]
}

Related

How do I write a MongoDB $exists query in Perl?

db.getCollection('Subscriber').find({$and:[{"registerFrom":{$exists:false}},{"googleRegistrationId":{$exists:true}},{"isGuest":"false"}]})
how to write the above query in Perl please help this.I am getting different results on this when execute on perl
i have written like this in perl
my $Subscriber2 = $Subscriber->find({'$and' =>[{dateOfJoining => {'$gt' => $date}},{registerFrom => { '$exists' => 'false'}},{googleRegistrationId => {'$exists' => 'true'}},{isGuest => 'false'}]})->fields({ _id => 1,streamzCampaigns => 1});
I am not getting the same results as when executing in perl.How to use $exits of mongoDB in Perl.Please help on this one.
The two suspicious bits I see are that you've quoted "true" and "false" -- which make those strings, not boolean values -- and I wonder what you're using for $date, since you don't have that in your shell example.
Here is what you wrote, formatted nicely:
my $Subscriber2 = $Subscriber->find(
{
'$and' => [
{ dateOfJoining => { '$gt' => $date } },
{ registerFrom => { '$exists' => 'false' } },
{ googleRegistrationId => { '$exists' => 'true' } },
{ isGuest => 'false' }
]
}
)->fields( { _id => 1, streamzCampaigns => 1 } );
For the booleans, you should use the boolean.pm module:
use boolean;
my $Subscriber2 = $Subscriber->find(
{
'$and' => [
{ dateOfJoining => { '$gt' => $date } },
{ registerFrom => { '$exists' => false } },
{ googleRegistrationId => { '$exists' => true } },
{ isGuest => false }
]
}
)->fields( { _id => 1, streamzCampaigns => 1 } );

Perl Elastic query broken after upgrade from 2.4 to 5

As the title suggests, I am upgrading to ES5. My original ES query looked like:
my $response = $elastic->do_request_new(
{
query => {
filtered => {
filter => {
or => [
{ term => { _type => { value => "some_val1" } } },
{ term => { _type => { value => "some_val2" } } },
]
},
query => {
query_string => {
query => $qstring,
rewrite => "scoring_boolean",
analyze_wildcard => "true",
}
}
}
},
sort => [ qw(_score) ],
size => 50,
},
);
My updated looks like:
my $response = $elastic->do_request_new(
{
query => {
bool => {
should => [
{ term => { _type => { value => "some_val1" } } },
{ term => { _type => { value => "some_val2" } } },
],
must => {
query_string => {
query => $qstring,
rewrite => "scoring_boolean",
analyze_wildcard => "true",
}
}
}
},
sort => [ qw(_score) ],
size => 50,
},
);
However, upon searching for exact strings in my elastic database, I am returning zero results:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
Any ideas about what might be happening? My guess is I have my query structure wrong. Thanks!
Update: The following fixed query:
my $response = $elastic->do_request_new(
{
query => {
bool => {
must => [
{
query_string => {
query => $qstring,
rewrite => "scoring_boolean",
analyze_wildcard => "true",
},
}
],
filter => {
bool => {
should => [
{ term => { _type => { value => "some_val1" } } },
{ term => { _type => { value => "some_val2" } } },
],
},
},
},
},
sort => [ qw(_score) ],
size => 50,
},
);

How to implement MongoDB query in Laravel 5?

I created mongodb query which I have to use in laravel controller.
My query is
db.PMS.aggregate([
{ $match: { "PanelID": "A00898" } },
{
$project: { EventTS: 1, MainsPower: 1, }
},
{
$unwind: {
path: "$MainsPower",
includeArrayIndex: "arrayIndex",
preserveNullAndEmptyArrays: true
}
},
{
$project: {
MainsPower: 1,
timestamp: {
"$add": [
"$EventTS",
{ "$multiply": [ 60000, "$arrayIndex" ] }
]
}
}
}
]);
I tried to use this query in a laravel function but I am little confused. Please help me how to implement this query in laravel.
Perform raw expressions on the internal MongoCollection object to run the aggregation:
$result = DB => collection('PMS')->raw(function ($collection){
return $collection->aggregate(array(
array( '$match' => array( "PanelID" => "A00898" ) ),
array( '$project' => array( 'EventTS' => 1, 'MainsPower' => 1 ) ),
array(
'$unwind' => array(
'path' => "$MainsPower",
'includeArrayIndex' => "arrayIndex",
'preserveNullAndEmptyArrays' => true
)
),
array(
'$project' => array(
'_id' => 0,
'MainsPower' => 1,
'timestamp' => array(
"$add" => array(
"$EventTS",
array( "$multiply" => array( 60000, "$arrayIndex" ) )
)
)
)
)
));
});

is there an option to unwind only when the array isn't empty?

i'm trying to run query with unwind. (aggregation)
the problem is that when i'm running unwind on an empty array I get empty result.
I know that this is a problem:
If the array holds an empty array ([]) in an input document, the
pipeline ignores the input document and will not output documents for
that input document. (from MongoDB docs)
is there an option that i can run 'unwind' only when the array i'm trying to unwind isn't empty?
EDIT:
$match = [
'_id' => ['$in' => $ids]
];
$project = [
'name' => true,
'sum1' => true,
'array1' => true,
'array2' => true,
'array3' => true
];
$group = [
'_id' => '$name',
'sum1' => ['$sum' => '$sum1'],
'array1' => ['$push' => '$array1'],
'array2' => ['$push' => '$array2'],
'array3' => ['$push' => '$array3']
];
$query = [
['$match' => $match],
['$project' => $project],
['$group' => $group],
['$unwind' => '$array1'],
['$unwind' => '$array2'],
['$unwind' => '$array3']
];
$ret = mongo_get_db()
->selectCollection("collection")
->aggregate($query);
EDIT2:
{
name: ‘name1’
sum1: 2
array1:
[
{
id: 111
name: 222
}
]
array2: []
array3: []
}
{
name: ‘name1’
sum1: 10
array1:
[
{
id: 122
name: 333
}
]
array2: []
array3: []
}
RESULT:
{
name: ‘name1’
sum1: 12
array1:
[
{
id: 111
name: 222
}
{
id: 122
name: 333
}
]
array2: []
array3: []
}
tnx :)
You could try a $match operator prior to the $unwind that filters documents which have the array that has at least an element, using the logic that there exists at least the first element indexed 0 in the array (with the dot notation):
{ $match: { "array_field.0": { $exists: true } } };
Why not simply check if the array is empty?
if(myArray.length === 0) { /* call your code here */ }

perl mongodb complex structure update

I have this structure:
{
"user" => "xxxx",
"position" =>
{
"A1" => { "state" => 'It', region=>"LOM" etc etc..},
"A2" => { .... },
"A3" => { .... },
....
"An" => { .. }
}
}
insert is ok. but update return this error:
not a reference at /usr/local/lib/perl/5.12.4/MongoDB/Collection.pm line 376
My update is:
$tbl->update({
{ _id => MongoDB::OID->new(value => "$id") },
{ '$set' =>
{
"position" =>
{
"A1" => { "state" => "En" }
}
}
}
});
Where I wrong?
Thks!
I check syntax of update source of MongoDB::Collection
syntax update
update (\%criteria, \%object, \%options?)
inside MongoDB::Collection method update
sub update {
my ($self, $query, $object, $opts) = #_;
...
}
but you pass only 1 parameter.
$tbl->update(
{ # 1st anonymous hash
{ _id => MongoDB::OID->new(value => "$id") },
{ '$set' => {
"position" => {
"A1" => { "state" => "En" }
}
}
}
});
So I advice you figure out with passed parameters to method update.