Local database integer data getting string when i push it to algolia - algolia

Records i'm pushing to algolia are showing as string however it's an integer in my local database.

Well you didn't put any code so I assume your error is here : Algolia is schemaless. You have to do it like said in this page :
{
"objectID": 42, // record identifier
"title": "Breaking Bad", // string attribute
"episodes": [ // array of strings attribute
"Crazy Handful of Nothin'",
"Gray Matter"
],
"like_count": 978, // integer attribute
"avg_rating": 1.23456, // float attribute
"featured": true, // boolean attribute
"actors": [ // nested objects attribute
{
"name": "Walter White",
"portrayed_by": "Bryan Cranston"
},
{
"name": "Skyler White",
"portrayed_by": "Anna Gunn"
}
]
}

Related

Updating Mongo DB collection field from object to array of objects

I had to change one of the fields of my collection in mongoDB from an object to array of objects containing a lot of data. New documents get inserted without any problem, but when attempted to get old data, it never maps to the original DTO correctly and runs into errors.
subject is the field that was changed in Students collection.
I was wondering is there any way to update all the records so they all have the same data type, without losing any data.
The old version of Student:
{
"_id": "5fb2ae251373a76ae58945df",
"isActive": true,
"details": {
"picture": "http://placehold.it/32x32",
"age": 17,
"eyeColor": "green",
"name": "Vasquez Sparks",
"gender": "male",
"email": "vasquezsparks#orbalix.com",
"phone": "+1 (962) 512-3196",
"address": "619 Emerald Street, Nutrioso, Georgia, 6576"
},
"subject":
{
"id": 0,
"name": "math",
"module": {
"name": "Advanced",
"semester": "second"
}
}
}
This needs to be updated to the new version like this:
{
"_id": "5fb2ae251373a76ae58945df",
"isActive": true,
"details": {
"picture": "http://placehold.it/32x32",
"age": 17,
"eyeColor": "green",
"name": "Vasquez Sparks",
"gender": "male",
"email": "vasquezsparks#orbalix.com",
"phone": "+1 (962) 512-3196",
"address": "619 Emerald Street, Nutrioso, Georgia, 6576"
},
"subject": [
{
"id": 0,
"name": "math",
"module": {
"name": "Advanced",
"semester": "second"
}
},
{
"id": 1,
"name": "history",
"module": {
"name": "Basic",
"semester": "first"
}
},
{
"id": 2,
"name": "English",
"module": {
"name": "Basic",
"semester": "second"
}
}
]
}
I understand there might be a way to rename old collection, create new and insert data based on old one in to new one. I was wondering for some direct way.
The goal is to turn subject into an array of 1 if it is not already an array, otherwise leave it alone. This will do the trick:
update args are (predicate, actions, options).
db.foo.update(
// Match only those docs where subject is an object (i.e. not turned into array):
{$expr: {$eq:[{$type:"$subject"},"object"]}},
// Actions: set subject to be an array containing $subject. You MUST use the pipeline version
// of the update actions to correctly substitute $subject in the expression!
[ {$set: {subject: ["$subject"] }} ],
// Do this for ALL matches, not just first:
{multi:true});
You can run this converter over and over because it will ignore converted docs.
If the goal is to convert and add some new subjects, preserving the first one, then we can set up the additional subjects and concatenate them into one array as follows:
var mmm = [ {id:8, name:"CORN"}, {id:9, name:"DOG"} ];
rc = db.foo.update({$expr: {$eq:[{$type:"$subject"},"object"]}},
[ {$set: {subject: {$concatArrays: [["$subject"], mmm]} }} ],
{multi:true});

MongoDb Query returning unwanted documents

I have a database containing documents of two structures:
{
"name": "",
"name_ar": "",
"description": "",
"bla1": {
"name": "",
"link": "",
"Logo": ""
},
"bla2": {
"name": "",
"id": ""
}
}
and
{
"name": "",
"name_ar": "",
"description": "",
"bla1": {
"name": [],
"link": "",
"Logo": ""
},
"bla2": {
"name": "",
"id": ""
}
}
I want to query my collection to get documents with "bla1.name" exactly equal to something. However using the following query:
{$and: [{'bla1.name': {'$type': 'string'}}, {"bla1.name":'something'}]}
returns all documents (even where "bla1.name" is an array) containing the name: 'something'.
What am I doing wrong?
From the MongoDB docs:
$type now works with arrays in the same way it works with other BSON types. Previous versions only matched documents where the field contained a nested array.
That means: If an array has at least one element with the given type it gets selected.
If you want to exclude arrays as type you have to extend your query. As the query already matches strings, you can exclude the type selection for string:
$and: [
// not necessary any more, as this selection is already implied by the last part
// {
// "bla1.name": {
// "$type": "string"
// }
// },
{
"bla1.name": {
$not: {
"$type": "array"
}
}
}, {
"bla1.name": "something"
}
]
See the official docs: https://docs.mongodb.com/manual/reference/operator/query/type/#behavior
Here is a working demo on the Mongo playground: https://mongoplayground.net/p/3ri7Bjfrae8

MongoDB UniqueIndex on EmbenddedDocuments [duplicate]

In my scenerio, there are authors in a collection, each author has messages and each message of author can has events. Each actor allowed to perform only one kind of action once.
db.people.ensureIndex({messages.messageEvents.eventName: 1, messages.messageEvents.actorId: 1}, {unique: true});
I added index but it has no effect. As you see below, my document has three elements which have "eventName":"vote" and "actorId":"1234" that should be against my constraint.
How to ensure unique item in messageEvents array based on eventName and actorId fields ?
Actually, i need to update the existing item without a second search and update event instead of rejecting it .
{
"_id": "1234567",
"authorPoint": 0,
"messages": [
{
"messageId": "112",
"messageType": "Q",
"messagePoint": 0,
"messageEvents": [
{
"eventName": "Add",
"actorId": "1234",
"detail": ""
},
{
"eventName": "Vote",
"actorId": "1234",
"detail": "up"
},
{
"eventName": "Vote",
"actorId": "1234",
"detail": "down"
},
{
"eventName": "Vote",
"actorId": "1234",
"detail": "cork"
}
]
}
]
}
Mustafa, unique constraints are not enforced within a single array, although they're enforced among documents in a collection. This is a known bug that won't be fixed for a while:
https://jira.mongodb.org/browse/SERVER-1068
There's a workaround, though. Keep your unique index in place, and:
1) Ensure your application does not insert new documents with duplicate values in the array. You can check for uniqueness in your application code before inserting.
2) When updating existing documents use $addToSet instead of $push.

Does the OData protocol provide a way to transform an array of objects to an array of raw values?

Is there a way specify in an OData query that instead of certain name/value pairs being returned, a raw array should be returned instead? For example, if I have an OData query that results in the following:
{
"#odata.context": "http://blah.org/MyService/$metadata#People",
"value": [
{
"Name": "Joe Smith",
"Age": 55,
"Employers": [
{
"Name": "Acme",
"StartDate": "1/1/1990"
},
{
"Name": "Enron",
"StartDate": "1/1/1995"
},
{
"Name": "Amazon",
"StartDate": "1/1/1999"
}
]
},
{
"Name": "Jane Doe",
"Age": 30,
"Employers": [
{
"Name": "Joe's Crab Shack",
"StartDate": "1/1/2007"
},
{
"Name": "TGI Fridays",
"StartDate": "1/1/2010"
}
]
}
]
}
Is there anything I can add to the query to instead get back:
{
"#odata.context": "http://blah.org/MyService/$metadata#People",
"value": [
{
"Name": "Joe Smith",
"Age": 55,
"Employers": [
[ "Acme", "1/1/1990" ],
[ "Enron", "1/1/1995" ],
[ "Amazon", "1/1/1999" ]
]
},
{
"Name": "Jane Doe",
"Age": 30,
"Employers": [
[ "Joe's Crab Shack", "1/1/2007" ],
[ "TGI Fridays", "1/1/2010" ]
]
}
]
}
While I could obviously do the transformation client side, in my use case the field names are very large compared to the data, and I would rather not transmit all those names over the wire nor spend the CPU cycles on the client doing the transformation. Before I come up with my own custom parameters to indicate that the format should be as I desire, I wanted to check if there wasn't already a standardized way to do so.
OData provides several options to control the amount of data and metadata to be included in the response.
In OData v4, you can add odata.metadata=minimal to the Accept header parameters (check the documentation here). This is the default behaviour but even with this, it will still include the field names in the response and for a good reason.
I can see why you want to send only the values without the fields name but keep in mind that this will change the semantic meaning of the response structure. It will make it less intuitive to deal with as a json record on the client side.
So to answer your question, The answer is 'NO',
Other options to minimize the response size:
You can use the $value OData option to gets the raw value of a single property.
Check this example:
services.odata.org/OData/OData.svc/Categories(1)/Products(1)/Supplier/Address/City/$value
You can also use the $select option to cherry pick only the fields you need by selecting a subset of properties to include in the response

How to Delete a Specific Object From The Arrayof Objects in MongoDB Casbah

mydata is look like below:-
{
"categories": [
{
"categoryname": "Eletronics",
"categoryId": "89sxop",
"displayname": "Eletronics",
"subcategories": [
{
"subcategoryname": "laptop",
"subcategoryId": "454",
"displayname": "Laptop"
},
{
"subcategoryname": "camera",
"subcategoryId": "sony123",
"displayname": "Camera"
}
]
}
]
}
I want to delete a specific object from a Subcategories Array
we are Trying like below code:-(This is to Delete Category)
val removingData = $pull(MongoDBObject("categories" -> MongoDBObject("categoryName" -> "Entertainment")))
this code is for removing Particular category.
But I Want To Remove ONE or MORE subCategories from particular category.
The subCategory(Ex:-i want to Delete camera Object from mydata) from the Electronics category
Expected Output:-(after deleting the camera Object)
{
"categories": [
{
"categoryname": "Eletronics",
"categoryId": "89sxop",
"displayname": "Eletronics",
"subcategories": [
{
"subcategoryname": "laptop",
"subcategoryId": "454",
"displayname": "Laptop"
}
]
}
]
}
Best Regards
GSY
You need to use the $pull operator, specifying the subcategories array and the condition used to pick the elements to remove. The $ operator can be used to select the subcategories array of the specific categories element you're interested in. See the Update Array Operators docs of mongo for details. Something like the following should work:
val query = MongoDBObject("categories.categoryname" -> "Electronics")
val removingData = $pull("categories.$.subcategories" -> MongoDBObject("subcategoryname" -> "camera"))
collection.update(query, removingData)
If you want to remove multiple subcategories, you can use the $or operator to specify multiple subcategorynames