Mongodb multikey index - mongodb

I want to make sure I'm creating the right index for my data structure (documents in mongodb).
My document contains list of items, and each item contain list of locations.
I'm searching for items using it's location, and I want to create the right index for this kind of search.
{ # <- document
"items": [
{ # <- first item
"name": "Item Name",
"locations": [
{ # <- first location
"sw":{"lat":0, "lng":0},
"ne":{"lat":0, "lng":0},
},
{ # <- second location
"sw":{"lat":0, "lng":0},
"ne":{"lat":0, "lng":0},
},
{ # <- more locations...
...
},
]
},
{ # <- second item
...
}
]
}
I'm searching for items using the lat and lng values, and I've used "ensureIndex" with the following key to create the index:
db.<collection>.ensureIndex({"items.locations.sw.lat":1});
db.<collection>.ensureIndex({"items.locations.sw.lng":1});
db.<collection>.ensureIndex({"items.locations.ne.lat":1});
db.<collection>.ensureIndex({"items.locations.ne.lng":1});
Is it the right way?
Thanks

Related

Only keep items that match string in array in Azure Data Factory

I have a very large array, similar to this one:
{
"name":"latest_test",
"value":[
{
"name":"2016-06-27-12Z",
"type":"Folder"
},
{
"name":"2016-06-28-00Z",
"type":"Folder"
},
{
"name":"2016-06-28-12Z",
"type":"Folder"
},
{
"name":"2016-06-29-00Z",
"type":"Folder"
},
{
"name":"2016-06-29-12Z",
"type":"Folder"
}
]
}
I only want to keep the items that have 2016-06-29 in their name. Such that I have a new array that only consists of 2016-06-29-00Z and 2016-06-29-12Z.
I tried to use a filter with #contains(item(), '2016-06-29') but this returns 0.
item() is the entire object for an element in the array. In order to filter on a property have to specify the property also.
Change the filter condition to
#contains(item().name, '2016-06-29')

mongodb query to get related data from relational collections

I have 6 collections:
A,B,C,D,E and F
the A collection has many relations with B collection:
one side is A collection.
many side is B collection.
collection A with coll_B_list field is connected to collection B.
collection B with coll_A field is connected to collection A.
collection A:
[
{id:"a1", coll_B_list:["b1", "b2", "b3", "b4"]},
{id:"a2", coll_B_list:["b5", "b6", "b7", "b8"]}
]
the B collection has one relation with collections C,D,E and F.
collection B with the coll_C field is connected to collection C.
collection B with the coll_D field is connected to collection D.
collection B with the coll_E field is connected to collection E.
collection B with the coll_F field is connected to collection F.
the collections C, D, E and F with the coll_B field are connected to collection B.
collection B:
[
{id:"b1", date:"2020-06-01", coll_A:"a1", coll_C:"c1", coll_D:"d2"},
{id:"b2", date:"2020-07-01", coll_A:"a1", coll_C:"c2"},
{id:"b3", date:"2020-05-01", coll_A:"a1", coll_C:"c3", coll_D:"d3", coll_E:"e1", coll_F:"f1"},
{id:"b4", date:"2020-08-01", coll_A:"a1", coll_C:"c4", coll_D:"d1", coll_E:"e2"},
{id:"b5", date:"2020-04-01", coll_A:"a2", coll_C:"c5", coll_D:"d4", coll_E:"e3"},
{id:"b6", date:"2020-01-01", coll_A:"a2", coll_C:"c6", coll_D:"d5", coll_E:"e4", coll_F:"f2"},
{id:"b7", date:"2020-10-01", coll_A:"a2", coll_C:"c7"},
{id:"b8", date:"2020-09-01", coll_A:"a2", coll_C:"c8", coll_D:"d6"}
]
collection C:
[
{id:"c1", coll_B:"b1", value:"v1"},
{id:"c2", coll_B:"b2", value:"v2" },
{id:"c3", coll_B:"b3", value:"v3" },
{id:"c4", coll_B:"b4", value:"v4" },
{id:"c5", coll_B:"b5", value:"v5" },
{id:"c6", coll_B:"b6", value:"v6" },
{id:"c7", coll_B:"b7", value:"v7" },
{id:"c8", coll_B:"b8", value:"v8" }
]
collection D:
[
{id:"d1", coll_B:"b4", value:"v9" },
{id:"d2", coll_B:"b1", value:"v10" },
{id:"d3", coll_B:"b3", value:"v11" },
{id:"d4", coll_B:"b5", value:"v12" },
{id:"d5", coll_B:"b6", value:"v13" },
{id:"d6", coll_B:"b8", value:"v14" }
]
collection E:
[
{id:"e1", coll_B:"b3", value:"v15" },
{id:"e2", coll_B:"b4", value:"v16" },
{id:"e3", coll_B:"b5", value:"v17" },
{id:"e4", coll_B:"b6", value:"v18" }
]
collection F:
[
{id:"f1", coll_B:"b3", value:"v19" },
{id:"f2", coll_B:"b6", value:"v20" }
]
I want Query that its result be like this:
coll_B_list field should :
sorted descending base on date field.
in the collections C,D,E and F :
- if exist related collection then show that
- else show the nearest collection
Result:
[
{
id:"a1",
coll_B_list:[
{
id:"b4",
date:"2020-08-01",
coll_C:{id:"c4", value:"v4"},
coll_D:{id:"d1", value:"v9"},
coll_E:{id:"e2", value:"v16"},
coll_F:{id:"f1", value:"v19"} // doesnt exist so get the nearest value
},
{
id:"b2",
date:"2020-07-01",
coll_C:{id:"c2", value:"v2"},
coll_D:{id:"d2", value:"v10"}, // doesnt exist so get the nearest value
coll_E:{id:"e1", value:"v15"}, // doesnt exist so get the nearest value
coll_F:{id:"f1", value:"v19"} // doesnt exist so get the nearest value
},
{
id:"b1",
date:"2020-06-01",
coll_C:{id:"c1", value:"v1"},
coll_D:{id:"d2", value:"v10"},
coll_E:{id:"e1", value:"v15"}, // doesnt exist so get the nearest value
coll_F:{id:"f1", value:"v19"} // doesnt exist so get the nearest value
},
{
id:"b3",
date:"2020-05-01",
coll_C:{id:"c3", value:"v3"},
coll_D:{id:"d3", value:"v11"},
coll_E:{id:"e1", value:"v15"},
coll_F:{id:"f1", value:"v19"} // doesnt exist so get the nearest value
}
]
},
{
id:"a2",
coll_B_list:[
{
id:"b7",
date:"2020-10-01",
coll_C:{id:"c7", value:"v7"},
coll_D:{id:"d6", value:"v14"}, // doesnt exist so get the nearest value
coll_E:{id:"e3", value:"v17"}, // doesnt exist so get the nearest value
coll_F:{id:"f2", value:"v20"} // doesnt exist so get the nearest value
},
{
id:"b8",
date:"2020-09-01",
coll_C:{id:"c8", value:"v8"},
coll_D:{id:"d6", value:"v14"},
coll_E:{id:"e3", value:"v17"}, // doesnt exist so get the nearest value
coll_F:{id:"f2", value:"v20"} // doesnt exist so get the nearest value
},
{
id:"b5",
date:"2020-04-01",
coll_C:{id:"c5", value:"v5"},
coll_D:{id:"d4", value:"v12"},
coll_E:{id:"e3", value:"v17"},
coll_F:{id:"f2", value:"v20"} // doesnt exist so get the nearest value
},
{
id:"b6",
date:"2020-01-01",
coll_C:{id:"c6", value:"v6"},
coll_D:{id:"d5", value:"v13"},
coll_E:{id:"e4", value:"v18"},
coll_F:{id:"f2", value:"v20"}
}
]
}
]
COLLECTIONS IN MONGOPLAYGROUND
NESTED $lookup in MONGOPLAYGROUND
NESTED $lookup in MONGOPLAYGROUND That Sorted

Limit number of items in group().by() in gremlin query

I am trying to run a gremlin query which groups vertices of a certain label into several groups by a certain field (assume it is 'displayName') and limit the number of groups to n and the number of items in each group also to n.
Is there a way to achieve that?
Since group().by() returns a list of the item, I tried using unfold() and then applying limit on the inner items. I managed to limit the number of groups that are returned, but couldn't limit the number of items in each group.
Here's the query I used to limit the number of groups:
g.V().hasLabel('customLabel').group().by('displayName').unfold().limit(n)
// Expected result:(if n == 2)
[
{
"displayName1": [
{ // item 1 in first group
},
{ // item 2 in first group
}
]
},
{
"displayName2": [
{ // item 1 in second group
},
{ // item 2 in second group
}
]
}
]
// Actual result: (when n == 2)
[
{
"displayName1": [
{ // item 1 in first group
},
{ // item 2 in first group
},
... // all the items are included in the result
]
},
{
"displayName2": [
{ // item 1 in second group
},
{ // item 2 in second group
},
... // all the items are included in the result
]
}
]
Currently, with the query above, I get only 2 groups "displayName1" and "displayName2", but each one contains all the items in it and not only 2 as expected.
If you want to limit the answer you can do it by defining the values for each key in the group:
g.V().hasLabel('customLabel')
.group()
.by('displayName')
.by(identity().limit(n).fold())
.unfold().limit(n)

Mongodb: assert that all elements in an array have a field not null

Given a collection with documents like this:
Task Collection document
[
{
"_id"=>BSON::ObjectId('54d674b64d42504b6a000000'),
"submissions"=>
[{"_id"=>BSON::ObjectId('54d674b64d42504b6a010000'),
"grade"=>nil,
"user_id"=>BSON::ObjectId('54d1e2454d42503069060000')},
{"_id"=>BSON::ObjectId('54d674b64d42504b6a020000'),
"grade"=>nil,
"user_id"=>BSON::ObjectId('54d1e2454d42503069070000')},
{"_id"=>BSON::ObjectId('54d674b64d42504b6a030000'),
"grade"=>nil,
"user_id"=>BSON::ObjectId('54d1e2454d42503069080000')}
],
},
{
"_id"=>BSON::ObjectId('54d674b64d42504b6a100000'),
"submissions"=>
[{"_id"=>BSON::ObjectId('54d674b64d42504b6a010000'),
"grade"=>5,
"user_id"=>BSON::ObjectId('54d1e2454d42503069060000')},
{"_id"=>BSON::ObjectId('54d674b64d42504b6a020000'),
"grade"=>7,
"user_id"=>BSON::ObjectId('54d1e2454d42503069070000')},
{"_id"=>BSON::ObjectId('54d674b64d42504b6a030000'),
"grade"=>nil,
"user_id"=>BSON::ObjectId('54d1e2454d42503069080000')}
],
},
{
"_id"=>BSON::ObjectId('54d674b64d42509b6a000000'),
"submissions"=>
[{"_id"=>BSON::ObjectId('54d674b64d42504b6a010000'),
"grade"=>8,
"user_id"=>BSON::ObjectId('54d1e2454d42503069060000')},
{"_id"=>BSON::ObjectId('54d674b64d42504b6a020000'),
"grade"=>7,
"user_id"=>BSON::ObjectId('54d1e2454d42503069070000')},
{"_id"=>BSON::ObjectId('54d674b64d42504b6a030000'),
"grade"=>6,
"user_id"=>BSON::ObjectId('54d1e2454d42503069080000')}
],
}
]
How can I get all the tasks documents whose submissions array contains no nil grade?
The result in the example would contain just the last one.
I am using Mongoid, but I welcome a pure Mongodb query too.
Using elem_match and a negative comparison:
Task.where(:submissions.elem_match => { :grade.ne => nil })

How do I create a Lithium - form->select from controller output

I want to create a dropdown for types collection from MongoDB, in my MongoDB collection:
section has types and controller code with view code. I want to create a form->select from the output of the controller.
types
{
"_id": ObjectId("5082c6109d5d0c640c000000"),
"name": "JACKET CLUSTER FRONT"
}
{
"_id": ObjectId("5082c62b9d5d0c440c00006e"),
"name": "JACKET CLUSTER FRONT"
}
{
"_id": ObjectId("5082c62b9d5d0c440c00006f"),
"name": "TITLE WITHOUT SYMBOL"
}
{
"_id": ObjectId("5082c62b9d5d0c440c000070"),
"name": "FRONTISPIECE"
}
*/
// in my controller
// -----------
$types = Types::all(array('order'=>'_id'));
$vtype = array($types)
return compact('vtypes');
// in my view
// ------------------
echo $this->form->select('types',$vtypes);
find('list') returns a key/value array, useful for any use where you would want a list such as for populating input select boxes.
$types = Types::find('list')
//returns
Array
(
[5082c6109d5d0c640c000000] => 'JACKET CLUSTER FRONT',
[5082c62b9d5d0c440c00006e] => 'JACKET CLUSTER FRONT',
[5082c62b9d5d0c440c00006f] => 'TITLE WITHOUT SYMBOL',
...
)
This finder looks for $_meta['title'] of your model, which is by default name if this field is available, and $_meta['key'] for the id, which should be _id in your case if your schema is correct
Finally, I used this to achieve the result.
Types::meta('key', '_id');
Types::meta('title', 'filename');
$types = Types::find('list',array(
'fields'=>array('id','filename'),
'order'=>'id'));