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')
I'm currently pulling every embedded object, that matches the given filters, from my mongodb collection. I then sort these and then .slice them to get the 10 objects the user actually needs depending on which page they are on, it looks like this.
const data = await EachWay.aggregate([
{
$unwind: "$data"
},
{
$match: filters
},
{
$project: {
"_id": 0,
"bookmaker": 1,
"sport": 1,
"data": 1
}
}
])
const start_index = (current_page - 1) * posts_per_page // included in results
const end_index = current_page * posts_per_page // won't be included in results
const shortened = data.sort((a, b) => {
if(Number(a.data.rating) < Number(b.data.rating)){
return 1
} else if(Number(a.data.rating) > Number(b.data.rating)){
return -1
} else {
return 0
}
}).slice(start_index, end_index).map(item => {
let result = item.data
result.bookmaker = item.bookmaker
result.sport = item.sport
return result
})
If the user is on page 3, this will get the 21st to the 30th post.
I feel like this is inefficient, as I'm having to pull every matching post from the database first, in some cases this can be 100,000 posts and then I only end up sending the client 10 of these. Is there a way to sort the embedded objects and pull the 21st-30th items from the database before returning the items?
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
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
this is my collection structure :
coll{
id:...,
fieldA:{
fieldA1:[
{
...
}
],
fieldA2:[
{
text: "ciao",
},
{
text: "hello",
},
]
}
}
i want to extract all fieldA2 in my collection but if the fieldA2 is in two or more times i want show only one.
i try this
Db.runCommand({distinct:’coll’,key:’fieldA.fieldA2.text’})
but nothing. this return all filedA1 in the collection.
so i try
db.coll.group( {
key: { 'fieldA.fieldA2.text': 1 },
cond: { } },
reduce: function ( curr, result ) { },
initial: { }
} )
but this return an empty array...
How i can do this and see the execution time?? thank u very match...
Since you are running 2.0.4 (I recommend upgrading), you must run this through MR (I think, maybe there is a better way). Something like:
map = function(){
for(i in this.fieldA.fieldA2){
emit(this.fieldA.fieldA2[i].text, 1);
// emit per text value so that this will group unique text values
}
}
reduce = function(values){
// Now lets just do a simple count of how many times that text value was seen
var count = 0;
for (index in values) {
count += values[index];
}
return count;
}
Will then give you a collection of documents whereby _id is the unique text value from fieldA2 and the value field is of the amount of times is appeared i the collection.
Again this is a draft and is not tested.
I think the answer is simpler than a Map/Reduce .. if you just want distinct values plus execution time, the following should work:
var startTime = new Date()
var values = db.coll.distinct('fieldA.fieldA2.text');
var endTime = new Date();
print("Took " + (endTime - startTime) + " ms");
That would result in a values array with a list of distinct fieldA.fieldA2.text values:
[ "ciao", "hello", "yo", "sayonara" ]
And a reported execution time:
Took 2 ms