JugglingDB MongoDB Array of IDs - mongodb

I'm using MongoDB adapter of Juggling-DB.
How can I run the equivalent of the following SQL query (IDs are fake)
SELECT * FROM APPS
WHERE
active = 1
AND (
user_id = '12345'
OR
id IN ('456', '789', '012')
)
that is "active apps that either belong to the given user or are available to all".
I tried the following:
{
where: {
active: true,
or: [
{
user_id: '12345'
},
{
_id: {
in: ['456', '789', '012']
}
}
]
}
}
But it returns nothing. Looking at the source code my wild guess is that it only converts strings to MongoDB.ObjectID when _id is a single string, not an array.

The mongodb query should be like:
db.apps.find({active: true, "$or": [{"user_id": "12345"}, {"_id": { $in: ['1', '2', '3']}}]})

Related

Return id based on existence of multiple value in mongodb

I want to return id based on certain condition like if a user value doesnot exist and both phone and email field matches with search condition with no available userId then i want to get the id of that specific row.If the userid exist it will not return anything.The idea of the query something like this:
db.records.find( { userId: { $exists: false } } )
db.records.find( { phone: "A", email:"B" }, { id: 1} )
how can i merge this query into one and return the only id in mongodb
You can add the queries with commas:
db.records.find( { userId: { $exists: false },phone: "A", email:"B" }, { id: 1} )
Here's an example:
https://mongoplayground.net/p/V_HL7WQqoiO

Group and Combine Text Fields Using Pymongo

I have a collection of user reviews and I'm trying to combine all the reviews by user so I can run some NLP analysis on them. This feels like it should be easy, but I'm missing something with how Mongo treats strings.
My documents look like this:
{'_id': ObjectId('57e079d3e3874f12ad721f70'),
'atmosphere': 5,
'review_id': 63,
'dedication': 3,
'orgName': 'Some Organization',
'enabled': True,
'accessibility': 3,
'efficiency': 3,
'orgId': '57e05e0de3874f121d516616',
'user': '5809f2c0bc0a53eb49eac583',
'date': '10/20/15 0:00',
'quality': 3,
'orgId_orig': 1098,
'description': 'Here is some sample text'
}
I've tried this:
agg_result = revs.aggregate( [
{ "$group": { "_id": "$user", "mergedText": { "$mergeObjects": "$description" } } }
])
for i in agg_result:
print(i)
But I'm getting this error:
OperationFailure: $mergeObjects requires object inputs, but input "Here is some sample text" is of type string
My expected output would be
{
'userId1':{'mergedText':'joined descriptions from this user'},
'userId2':{'mergedText':'this users descriptions'},
'userId3':{'mergedText':'all descriptions from this user'}
}
where the various userIds are Mongo ObjectIds from the 'user' field.
I'm brand new to Mongo and this has been tripping me up for awhile. Thank you.
try this , merge object needs objectbut your description is string you could push in array
agg_result = revs.aggregate( [
{ "$group": { "_id": "$user", "mergedText": { "$push": "$description" } } }
])
for i in agg_result:
print(i)

How to combine $in and $elemMatch properly with MongoDB (PyMongo)

In my database, I've got data stored according to the following scheme:
{'_id': ...,
'names': [{'first': ...,
'last': ...},
{'first': ...,
'last': ...},
...
],
...
}
Now, in my program, I get a list of names according to the following scheme:
name_list = [(first_name1, last_name1), (first_name2, last_name2), ...]
What I want, is to find all documents where any of these combinations of first/last name found in name_list are contained in the names array.
If I'd have just one name to check (instead of a list), I'd use the following query:
query = {'names':
{'$elemMatch':
{'first_name': first_name,
'last_name': last_name}
}}
So I could supply this query for every name in the list, doing something like:
all_results = []
for first_name, last_name in name_list:
rv := # Result from query
# combine all_results and rv
But I feel like there should be a better way to do this.
A multi-elem match query could be created from name_list using $or and $elemMatch which works in a way to find the documents where any of those first/last combination matches.
Query: considering name_list to be
//[(first_name1, last_name1), (first_name2, last_name2), (first_name3, last_name3)]
db.collection.find({
$or: [
{
names: {
$elemMatch: {
first: "first_name1",
last: "last_name1"
}
}
},
{
names: {
$elemMatch: {
first: "first_name2",
last: "last_name2"
}
}
},
{
names: {
$elemMatch: {
first: "first_name3",
last: "last_name3"
}
}
}
]
});

Mongodb: Get last item from array in document

I have a collection in MongoDB with elements looking like this
{
userId: 'X',
access: [
{ deviceId: 'a', time: "A timestamp" },
{ deviceId: 'b', time: "Another timestamp" },
]
}
I want to match documents based on userId and then I want to get the last element in the access array. The value I am most interested in here for user with id "X" is "Another timestamp".
I do not want mongodb to return the entire document, just that last element and always the last one.
How can I write a query/aggregation that solves this?
Try using $slice:
db.collection.find({ userId: 'value' }, { access: { $slice: -1 } } )

Using upsert with subdocument and positional operator '$'

I have a collection like the following:
{
_id: ...,
userId: test,
cards: [
{ cardId: 166, qty: 2 },
...
]
}
I can send the following query to mongo to update a specific card:
db.getCollection('collections').update(
{ 'userId': 'test', 'cards.cardId': 166},
{ $set: {"cards.$.qty": 3} }
)
I also want to be able to create the card if it doesn't exist (ie. no card with such id) but the documentation says:
Do not use the positional operator $ with upsert operations because
inserts will use the $ as a field name in the inserted document.
Is there any way around this? Can I do an update-if-exists/create with a single request to the database?
try this way
db.getCollection('collections').update(
{ 'userId': 'test', 'cards.$.cardId': 166},
{ $set: {"cards.$.qty": 3} }
)
or
db.getCollection('collections').update(
{ 'userId': 'test', 'cards.0.cardId': 166},
{ $set: {"cards.0.qty": 3} }
)