MongoDB aggregate to filter - node.js

I have this aggregate in Python working without 0 issues
mycol.aggregate([
{
'$match': {
'Extention': '100',
'FinalUnicode': {
'$ne': ''
}
}
}
I am now working with NodeJS and Express. I have this so far but can't seem to give it the FinalUnicode filter. Currently it works by returning the Extentions that are equal to 100.
query = { "Extention": { $eq: filters["ext"] } }

You can use find() like this:
mycol.find({ Extention: '100', FinalUnicode: { $ne: '' }});
Or you can literally copy/paste aggregation code that you have in Python.

Related

MongoDB - Compare the field value with array size

I'm trying to return all documents which satisfy document.field.value > document.array.length. I'm trying to do this using MongoClient in ExpressJS and was not able to find answers on SO.
Here is what I have tried but this gives an empty list.
const db = ref()
const c = db.collection(t)
const docs = await c.find({
"stop.time":{$gt: new Date().toISOString()},
"stop.expect": {$gt: { $size: "stop.riders"}}
})
console.log(docs)
Also tried replacing
"stop.expect": {$gt: { $size: "stop.riders"}}
with the below code which does not compile
$expr: {$lt: [{$size: "stop.riders"}, "stop.expect"]}
Sample data:
{ "stop": { "expect":3, "riders": ["asd", "erw", "wer"] } },
{ "stop": { "expect":4, "riders": ["asq", "frw", "wbr"] } }
To filter the query with a complex query involving the calculation, you need to use the $expr operator, which allows the aggregation operators.
Next, within the $expr operator, to refer to the field, you need to add the prefix $.
db.collection.find({
$expr: {
$lt: [
{
$size: "$stop.riders"
},
"$stop.expect"
]
}
})
Demo # Mongo Playground
To compare fields within a document to each other, you must use $expr. It would look like this:
const docs = await c.find({
$expr: { $gt: ["$stop.expect", { $size: "$stop.riders" }] },
});
I omitted the stop.time condition because it's not in your sample data and it's unclear what type of field it is, if it actually is in your data (whether it's a Date or String would be very important).
Note that this sort of query is unable to use an index.

Mongo (Node Js , Keystone ) field selection and slice cannot be used with distinct Error:

How do we integrate both distinct and selects the documents where the value of the field is not equal to the specified value.in a query in mongo using nodejs (keystone framework) ? or just basically in mongo. I am receiving an error which is field selection and slice cannot be used with distinct Error:. Any idea? or solution? I did try to use Syntax: {field: {$ne: value} } and that is the error. Also how can we include a limit when limit cannot be used with distinct Error: limit cannot be used with distinct.
query
keystone.list('Customer').model.find({ customer_id: { $in: locals.data.customers } }, { vin: { $ne: vin } }).distinct('vin').limit(4) ....
You can add a query to distinct but not skip and limit
https://docs.mongodb.com/manual/reference/method/db.collection.distinct/#specify-query-with-distinct
Instead, you can use the aggregate pipeline as
db.customer.aggregate(
{ $match:{ customer_id: { $in: locals.data.customers } }},
{ $group:{_id:"$vin"}},
{ $skip: skip},
{ $limit: limit},
{ $group:{_id:null,vin:{$push:"$_id"}}}
);

How to fetch an object in Moogose

I'm trying to learn Mongoose and I'm trying to make a simple project. However, I can't understand how to do this.
I have a Schema like this (below) and I want to try to fetch results in this way...
Example: I want to get roleID where gameID is 111
How can do it?
I tried to search solution on google but I still don't understand how to make it without create object for any game I put in array
If I correctly understand you, you need something like this
aggregate(
[
{
$unwind: '$games'
},
{
$match: {
'games.gameId': "111"
}
},
{
$group: {
_id: '$games.gameId',
roles: {
$addToSet: '$games.roleId'
}
}
}
]
)

$addToSet aggregation and multiple arrays

I have this collection :
[
{
_id: ObjectId('myId1'),
probes: ['id_probe_1', 'id_probe_2']
},
{
_id: ObjectId('myId2'),
probes: ['id_probe_1', 'id_probe_3']
}
]
I want to get an array like this :
['id_probe_1', 'id_probe_2', 'id_probe_3']
So I try this request (from nodeJS driver) :
let find = [
{
$match: {
_id: {
$in: [new ObjectId('miId1'), new ObjectId('myId2')]
}
}
},
{
$group: {
_id: null,
probes: {
$addToSet: {
$each: '$probes'
}
}
}
}
];
This doesn't work, give me this error :
invalid operator '$each'
From the doc, they mention that it will appends the whole array as a single element.
If the value of the expression is an array, $addToSet appends the whole array as a single element.
But they don't say how to have an unique array. So I use the $each operator like this page indicates (I don't really know what's the difference...)
Is there a way to make this work ?
Thanks !
insert $unwind before $group
{$unwind:"$probes"},
then remove $each
Why don't you try distinct operation? In mongo shell, db.col.distinct('probs'); you can try the distinct function in nodejs mongo driver.

How to match any location from a given list of coordinates in MongoDB?

I am currently using MongoDB with node.js and Mongoose to perform geospatial searches.
I'm working with the following documents and collections:
waypoints are documents that contain location and other metadata (just is there, not otherwise relevant for this question)
targets collection contains 1...n waypoints
sources collection contains exactly 1 waypoint
Simple example of what these documents may look like:
// Target
{
waypoints: [
{
loc: [61.24, 22.24],
time: 0
},
{
loc: [61.25, 22.24],
time: 1
},
{
loc: [61.26, 22.24],
time: 2
},
]
}
// Source
{
waypoint: {
loc: [61.24, 22.24],
time: 0
}
}
So my question is this:
Given that we have a specific target document (like the one above), what is the easiest way to find all source documents near (within distance of MAX_DISTANCE) any of the given waypoints in the target?
Matching for single waypoint is trivial:
Source.find({
'from.loc': {
$within: {
$center: [target.waypoints[0].loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
})
However I'm struggling to find the solution of how to match any of the given waypoints. For instance the following query doesn't work:
Source.find({
$or: [
{
'waypoint.loc': {
$within: {
$center: [target.waypoints[0].loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
},
{
'waypoint.loc': {
$within: {
$center: [target.waypoints[1].loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
},
{
'waypoint.loc': {
$within: {
$center: [target.waypoints[2].loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
}
]
})
Any ideas why this doesn't work and what would be the alternative?
All help is much appreciated!
P.S. I'm using MongoDB v2.0.5, Mongoose 2.7.4 & node v0.8.7
$or queries are implemented as separate queries internally anyway, so aside from a lack of elegance, something like the following works w/o too much bloat (with a little help from the underscore library):
var nearSources = {}, count = target.waypoints.length;
target.waypoints.forEach(function (waypoint) {
Source.find({
'waypoint.loc': {
$within: {
$center: [waypoint.loc, MAX_DISTANCE],
$uniqueDocs: true
}
}
}, function (err, sources) {
if (sources) {
// Add the unique sources to the nearSources object by _id.
sources.forEach(function (source) {
nearSources[source._id] = source;
});
}
if (--count === 0) {
// Done! Convert nearSources to an array of source docs.
nearSources = _.values(nearSources);
}
});
});

Resources