How to get the nested object values in mongodb? - mongodb

How do I perform the filter in collection. For example I've the collection of data like this and I want to do this rits_dbx_1>0.2,simon_dbx_1<0.5
{
"threads":{
"threads_participants":{
"participant":[
{
"#all_user_n_grams":"0",
"#reference":"rits_dbx_2",
"overall_user_participation":"0.0",
"thread":{
"#thread_id":"5e778ea6a28f9a3881c330b4",
"#text":"{'relative_to_thread_interactors': 0.0, 'relative_to_self_threads': 0}"
}
},
{
"#all_user_n_grams":"11",
"#reference":"rits_dbx_1",
"overall_user_participation":"1.0",
"thread":{
"#thread_id":"5e778ea6a28f9a3881c330b4",
"#text":"{'relative_to_thread_interactors': 1.0, 'relative_to_self_threads': 1.0}"
}
}
]
}
}
}
First I tried to get the value using the find method.
db.xml_collection.find({"threads.threads_participants.participant": {"#reference": "rits_dbx_2"}})
Also it returned nothing. Can you help with the above condition.

I understood that you you are trying to find
"#reference":"rits_dbx_2" and "overall_user_participation":["$gt":0.5]
or
"#reference":"simon_dbx_1" and "overall_user_participation":["$lt":0.2]
if so:
list(db.xml_collection.find({"$or": [{"threads.threads_participants.participant.#reference":"rits_dbx_2","threads.threads_participants.participant.overall_user_participation":{"$gt":"0.2"}},{"threads.threads_participants.participant.#reference":"simon_dbx_1","threads.threads_participants.participant.overall_user_participation":{"$lt":"0.2"}}]}))
I also recommend you to use float instead of string for overall_user_participation field to improve comparing performance and correctness.

Related

Fetch a random record from a Realm database (Swift)

I am trying to fetch a random record from my Swift Realm database.
I have previously used the sample function in mongoDB, so I thought there must be an equivalent in Realm (it's based on mongoDB, right?)
I can't find any documentation on such a function, and I've only found search results which suggest to fetch the entire collection then choose a random record [1, 2]. Obviously, this is inefficient.
Am I missing something obvious, is there a better way to do it?
See below for an example mongoDB query:
db.Words.aggregate([
{ $match: { gender: gender } },
{ $sample: { size: 1 } }
])
For clarity the code in the question is not part of the Realm Swift SDK for local or sync but it is a query directly to Atlas using app services, so it would be valid for non-sync'ing or non-local applications. (Use the Swift SDK if possible!)
If we're doing this using the SDK, you can actually leverage high-level Swift functions to return a result using .randomElement()
So given a PersonClass that has a name property
class PersonClass: Object {
#Persisted var name = ""
}
we can this use this code to return a random person from Realm and output their name to console
if let randomPerson = realm.objects(PersonClass.self).randomElement() {
print(randomPerson.name)
} else {
print("no data was returned)")
}

JSONB filter on select via Supabase

I have such a logic (attributes column's type is JSONB - array of objects) that works:
But I want to implement logical OR here if trait_type is equal ... not AND:
JSONB's column structure:
[
{
"value":"Standard Issue Armor 1 (Purple)",
"trait_type":"Clothes"
},
{
"value":"Standard Issue Helmet 1 (Red)",
"trait_type":"Full Helmet"
},
{
"value":"Chrome",
"trait_type":"SmartSkin"
},
{
"value":"Base Drone (Blue)",
"trait_type":"Drone"
},
{
"value":"Thick",
"trait_type":"Eyebrows"
}
]
How that could be done?
Thanks in advance!
I didn't verify the code, so might not work, but I believe at least is in the right direction. You can use the .or() filter to connect multiple filters with logical or operator. For contains(), you can use the cs keyword inside the or filter like this:
const { data, error } = await supabase.from('NTFs')
.select('name, id_in_collection, owner_address')
.eq('collection_id', Number(id))
.contains('attributes', JSON.stringify([{trait_type: 'SmartSkin', value: 'Chrome'}]))
.or(`attributes.cs.${JSON.stringify([{trait_type: 'Drone', value: 'Armed Drone (Blue)'}])}`, `attributes.cs.${JSON.stringify([{trait_type: 'Drone', value: 'Armed Drone (Green)'}])}`)
.order('id_in_collection')
.range(fromIndex, toIndex)

Remove a specific nested object from an array of objects

I need to remove a specific object that is nested inside an array of objects.
The following db structure looks like:
I would like to remove one of the teams based on the roomId (to find the specific room) and based on the team approved state. If a team has "approved: false" it needs to be deleted from the array of objects.
I'm using mongoose and came up with the following, but without succes:
Room.update({"roomId": req.params.roomId},
{"$pull": { "teams.approved": false } })
screenshot thats shows the correct roomId:
The array name and equality condition should be specified separately like in this example, try:
await Room.update({"roomId": req.params.roomId}, {"$pull": { "teams": { approved: false } } })
Room.updateOne({ roomId: req.params.roomId}, {"$pull": { "teams": { approved: false } } })
This might work for your case.
I think something like this should work:
Room.find({roomId: 1234}).then((result) => {
if (result) {
return Room.remove({result.teams.approved: false})
}
} ).catch()
You still need to first find all results matching the roomId number and then removing the teams based on approved. There are probably better ways to handle this but I think it's a fair approach.

How to remove property from each item in object with MongoDB

I have an object in my document like this:
revisions: {
<revisionId>: {
...
someProperty: { ... },
},
...
}
I would like to remove someProperty from every nested object in revisions object (i.e. iterate through all the object revisionId keys). I'm asking because if it's not possible I'd rather convert this to an array than do it on the server and possibly overwrite any updates in the mean time.
I tried $unset but I'm only aware of the $[] operator which only works for arrays e.g.
$unset: {
'revisions.$[].someProperty': 1
}
Thanks
You're almost there:
{ $unset: { someProperty: "" } }
The value doesn't matter from memory
You could then use a cursor to iterate through each doc and remove the unwanted property.
db.collection.find().forEach(<function>)
EDIT: Sorry, realising it's a nested model with arbitrary key for the top level property, makes it more tricky.
t.forEach(function( row) {
var newRevisions = [];
row.revisions.fields.forEach( function( revision ){
delete revision.someProperty;
newRevisions.push(revision);
} )
t.update(
{ _id: row._id },
{ "$set": { "revisions": newRevisions} }
);
});
Huge caveat, totally untested, but should give you starting point.
For each row
For each revision in revisions object
Remove the someProperty property
Set the revisions property back the collection based on _id

Update nested array object (put request)

I have an array inside a document of a collection called pown.
{
_id: 123..,
name: pupies,
pups:[ {name: pup1, location: somewhere}, {name: pup2, ...}]
}
Now a user using my rest-service sends the entire first entry as put request:
{name: pup1, location: inTown}
After that I want to update this element in my database.
Therefore I tried this:
var updatedPup = req.body;
var searchQuery = {
_id : 123...,
pups : { name : req.body.name }
}
var updateQuery = {
$set: {'pups': updatedPup }
}
db.pown.update(searchQuery, updateQuery, function(err, data){ ... }
Unfortunately it is not updating anythig.
Does anyone know how to update an entire array-element?
As Neil pointed, you need to be acquainted with the dot notation(used to select the fields) and the positional operator $ (used to select a particular element in an array i.e the element matched in the original search query). If you want to replace the whole element in the array
var updateQuery= {
"$set":{"pups.$": updatedPup}
}
If you only need to change the location,
var updateQuery= {
"$set":{"pups.$.location": updatedPup.location}
}
The problem here is that the selection in your query actually wants to update an embedded array element in your document. The first thing is that you want to use "dot notation" instead, and then you also want the positional $ modifier to select the correct element:
db.pown.update(
{ "pups.name": req.body.name },
{ "$set": { "pups.$.locatation": req.body.location }
)
That would be the nice way to do things. Mostly because you really only want to modify the "location" property of the sub-document. So that is how you express that.