When I run mongo db I get this :
$ ./mongo db
MongoDB shell version: 2.4.2
connecting to: db
Server has startup warnings:
** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
Mon Apr 22 19:25:54.938 [initandlisten] Index { v: 1, key: { type: "text", color: "text", category_A: "text", category_B: "text", category_C: "text" }, ns: "db.items", name: "type_text_color_text_category_A_text_category_B_text_category_C_text", sparse: false, background: false } claims to be of type 'text', which is either invalid or did not exist before v2.4. See the upgrade section: http://dochub.mongodb.org/core/upgrade-2.4
> db.adminCommand( { setParameter : 1, textSearchEnabled : true } )
{ "was" : false, "ok" : 1 }
> db.runCommand("text",{search:"le"})
{
"errmsg" : "exception: wrong type for field (text) 1 != 2",
"code" : 13111,
"ok" : 0
}
when I run the following code with nodejs I get -
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Items = new Schema({
type : { type : String , default:""},
color : { type : [String] , default:""},
category_A : { type : String , default:""},
category_B : { type : String , default:""},
category_C : { type : String , default:""},
});
var textSearch = require("mongoose-text-search");
var ItemModel = mongoose.model('Item', Items);
Items.plugin(textSearch);
Items.index({
type :"text",
color :"text",
category_A :"text",
category_B :"text",
category_C :"text"
},
{
name: "best_match_index",
weights: {
type: 5,
color: 4,
}
}
)
ItemModel.textSearch('D', function (err, output) {
if (err)
console.log(err);
else
console.log(output)
})
running this I get :
ItemModel.textSearch('D', function (err, output) {
^
TypeError: Object function model() {
Model.apply(this, arguments);
} has no method 'textSearch'
Having a same issue here.
I resolved it by applying code from /mongoose-text-search/lib/index.js
YOURSCHEMA.statics.textSearch = function (search, o, cb) {
if ('function' == typeof o) cb = o, o = {};
if ('function' != typeof cb) {
throw new TypeError('textSearch: callback is required');
}
var model = this;
var lean = !! o.lean;
// mongodb commands require property order :(
// text must be first
var cmd = {};
cmd.text = o.text || this.collection.name;
cmd.search = search;
var keys = Object.keys(o);
var i = keys.length;
while (i--) {
var key = keys[i];
switch (key) {
case 'text':
// fall through
case 'lean':
continue;
case 'filter':
cmd.filter = model.find(o.filter).cast(model);
break;
case 'project':
// cast and apply default schema field selection
var query = model.find().select(o.project);
query._applyPaths();
var fields = query._castFields(query._fields);
if (fields instanceof Error) return cb(fields);
cmd.project = fields;
break;
default:
cmd[key] = o[key];
}
}
this.db.db.command(cmd, function (err, res) {
if (err) return cb(err, res);
if (res.errmsg) return cb(new Error(res.errmsg));
if (!lean && Array.isArray(res.results)) {
// convert results to documents
res.results.forEach(function (doc) {
if (!doc.obj) return;
var d = new model(undefined, undefined, true);
d.init(doc.obj);
doc.obj = d;
})
}
cb(err, res);
});
}
}
to my local schema file
One thing to double-check is that you're not overriding the statics property after you've applied the plugin. This is what was causing the problem for me.
mySchema.plugin(textSearch);
mySchema.index({ name: 'text' });
...
mySchema.statics = { ... }
Related
I try to update a record, following the documentation here . But After I check the record it is not updated. I filter the object correctly but when I try to set hasSentEntry to a boolean it seems to not affect it.
If I try to update with the second method( Upsert an Object in docs ). The program crashes and closes before I could print the error. How can I solve this? I can't understand the reason.
Here is the schema:
const AttendanceSchema = {
name: ATTENDANCE_SCHEMA,
primaryKey: "_id",
properties: {
_id: "objectId",
KartId: "string?",
entryTime: "string?",
exitTime: "string?",
photo: "string?",
hasSentEntry: "bool?",
hasSentExit: "bool?",
},
};
Here is the database options with migration:
const databaseOptions = {
path: "/var/lib/realm/local.realm",
schema: [
AttendanceSchema,
],
schemaVersion: 2,
migration: (oldRealm, newRealm) => {
if (oldRealm.schemaVersion < 3) {
const oldSchema = oldRealm.objects(ATTENDANCE_SCHEMA);
const newSchema = newRealm.objects(ATTENDANCE_SCHEMA);
newSchema.hasSentEntry = oldSchema?.hasSentEntry ? true : false;
newSchema.hasSentExit = oldSchema?.hasSentExit ? true : false;
}
},
};
How I try to update it:
realm.write(() => {
const attendanceData = realm
.objects("Attendance")
.filtered("photo=='" + filePath + "'");
attendanceData.hasSentEntry = true;
});
This is the upset version:
delete attendance.hasSentEntry;
try {
const modifiedAttendance = realm.create(
"Attendance",
{ ...attendance, hasSentEntry: true },
"modified"
);
} catch (e) {
console.log("Error??", e);
}
Actually, I'm a newbie to graphQL so I wasn't able to pass parameters rightly in function updateMessage() in graphiQL. I'm trying to update the database using
mutation {
createMessage(input: {
author: "Pawan",
content: "hope is a dangerous thing",
}) {
id,content,author,
}
updateMessage(id:{cfe934d60b9997a4507e},input:{
author: "Pawan",
content: "hope is a dangerous thing",
})
}
but the error is displayed as
{
"errors": [
{
"message": "Syntax Error: Expected :, found }",
"locations": [
{
"line": 8,
"column": 40
}
]
}
]
}
Beside I'm also not able to show fakeDatabase .Can I do that ?
if yes How can I show every time I add a message to the fakeDatabase?
mutation.js
var express = require('express');
var graphqlHTTP = require('express-graphql');
var { buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
input MessageInput {
content: String
author: String
}
type Message {
id: ID!
content: String
author: String
}
type Query {
getMessage(id: ID!): Message
}
type Mutation {
createMessage(input: MessageInput): Message
updateMessage(id: ID!, input: MessageInput): Message
}
`);
// If Message had any complex fields, we'd put them on this object.
class Message {
constructor(id, {content, author}) {
this.id = id;
this.content = content;
this.author = author;
}
}
// Maps username to content
var fakeDatabase = {};
var root = {
getMessage: function ({id}) {
if (!fakeDatabase[id]) {
throw new Error('no message exists with id ' + id);
}
return new Message(id, fakeDatabase[id]);
},
createMessage: function ({input}) {
// Create a random id for our "database".
var id = require('crypto').randomBytes(10).toString('hex');
fakeDatabase[id] = input;
return new Message(id, input);
},
updateMessage: function ({id, input}) {
if (!fakeDatabase[id]) {
throw new Error('no message exists with id ' + id);
}
// This replaces all old data, but some apps might want partial update.
fakeDatabase[id] = input;
return new Message(id, input);
},
};
var app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
console.log(fakeDatabase)
app.listen(4000, () => {
console.log('Running a GraphQL API server at localhost:4000/graphql');
});
On your mutation updateMessage try updating the parameters and send $id as a string instead of an object, like:
updateMessage(id:"cfe934d60b9997a4507e",input:{
author: "Pawan",
content: "hope is a dangerous thing",
})
The issue is that mutation updateMessage requires an ID and MessageInput, but you're sending Object and MessageInput.
data in database
fieldA : 'aaaaa',
fieldB : {
en : 'aaaaaaaaaa',
de : 'bbbbbbbbbb'
}
new data
val = {
fieldA : 'aaaaa11',
fieldB : {
en : 'aaaaa1111'
}
}
i tried this code
Model.findOneAndUpdate({fieldA : val.fieldA},{ $set : val})
when i run this command 'fieldB.de' is missing. i want to know how to update as result seem below
fieldA : 'aaaaa11',
fieldB : {
en : 'aaaaa1111',
de : 'bbbbbbbbbb'
}
Try this:
Model.findOneAndUpdate({fieldA : val.fieldA},{
"$set": {
"fieldA": val.fieldA,
"fieldB.en": val.fieldB.en
}
})
In your solution you update document completny with other one. To update only specific fields you must specify this fields in "$set" object
I resolve this by finding the document first and editing de object manually.
/* Recursive function to update manually an object */
const update = (obj, newValues) => {
Object.entries(newValues).forEach( ([key, value]) => {
if(typeof value === 'object'){
update(obj[key], value);
} else {
obj[key] = value;
}
});
}
/* Find document, update and save */
const infoToUpdate = {};
const doc = await Model.findOne({ field: valueToFind });
if (doc) {
object.update(doc, infoToUpdate);
doc.save();
}
You have to change the object passed to findOneAndUpdate() so that you don't pass fieldB as an object, only the fields to update.
It can be done with something like this:
let val = {
fieldA: 'aaaaa11',
fieldB: {
en: 'aaaaa1111',
},
};
if (val.fieldB) {
const newFieldB = Object.entries(val.fieldB).reduce(
(a, [key, value]) => ({ ...a, ['fieldB.' + key]: value }),
{}
);
delete val.fieldB;
val = { ...val, ...newFieldB };
}
Model.findOneAndUpdate({fieldA : val.fieldA},{ $set : val})
With that, the value of val passed to findOneAndUpdate() is:
{
fieldA: 'aaaaa11',
'fieldB.en': 'aaaaa1111',
}
Instead of:
{
fieldA: 'aaaaa11',
fieldB: {
en: 'aaaaa1111',
},
}
... and attributes of fieldB that you didn't specify in val but that were in your DB will not get overridden.
I thought I could read my way to this solution, but I cant see what im doing wrong.
Here is my model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var inspectSchema = new Schema({
_id: Object, // Mongo ID
property: String, // Property ID
room: String, // The room Name
item: Array // The Items text
});
module.exports = mongoose.model('inspectModel', inspectSchema, 'inspect');
And here is where I try to insert or insertOne
var inspectModel = require('../../models/inspectModel');
var inspectTable = mongoose.model('inspectModel');
inspectTable.insert(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
},
function (err, res) {
if (err) { return reject({err:true, err:"addInspect ERROR" + err}) }
else {
show("=====RESOLVE addInspect=====")
return resolve();
}
})
I tried
inspectTable.insert
inspectModel.insert
inspectTable.insertOne
inspectModel.insertOne
No matter what I always get
TypeError: inspectTable.insert is not a function
I also tried just update with { upsert: true } but then the mongo ID becomes null.
Any ideas?
The method you're looking for is create:
inspectTable.create(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
}, ...
However, your schema definition of _id: Object is likely wrong. Just leave any definition of _id out of your schema and it will use the default ObjectId, which is likely what you want.
You can try this
var insert_table = new inspectTable(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
});
insert_table.save(function (err, res) {
if (err) { return reject({err:true, err:"addInspect ERROR" + err}) }
else {
show("=====RESOLVE addInspect=====")
return resolve();
}
});
EDIT: Resolved. It was just missing a bracket at the end of the if statement.
Thank you for your time!
The line at which I used Hotel.find doesn't appear to be executed, so the code below it doesn't work at all. I didn't get any errors or warnings. It just doesn't do anything. I don't understand what I did wrong.
function getPlaces() {
mongoose.connect("mongodb://localhost:27017/gtdb");
var db = mongoose.connection;
db.on("error", console.error.bind(console, "Connection error:"));
db.once("open", function(callback) {
//Define the hotel schema.
var Schema = mongoose.Schema;
var hotelSchema = new Schema({
"PlaceName" : String,
"PlaceType" : String,
"PlaceAddress" : String,
"Telephone" : String,
"PlaceCity" : String,
"ZipCode" : Number,
"State" : String,
"Country" : String,
"EstimatedPrice" : Number,
"PhotoUrl" : String,
"OtherDetails" : String
});
var Hotel = mongoose.model("Hotel", hotelSchema);
if (searchtype == "Hotel") {
console.log("Request received for hotel data.");
Hotel.find(function(err, hotels) { //This is the line it won't execute.
var i;
console.log(hotels);
console.log("Find test");
for (i = 0; i < hotels.length; i++) {
dataarray[i] = hotels[i];
}
});
} else if (searchtype == "Event") {
Event.find(function(err, events) {
});
}
mongoose.disconnect();
}); //End of db.once function.
} //End of the getPlaces function.
Thank you for your time.