Azure Search - Error - azure

When trying to index documents we are getting this error:
{"Token PropertyName in state ArrayStart would result in an invalid JSON object. Path 'value[0]'."}
Our code for indexing using the .NET library is :
using (var indexClient = new SearchIndexClient(searchServiceName, indexName, new SearchCredentials(apiKey)))
{
indexClient.Documents.Index(IndexBatch.Create(IndexAction.Create(documents.Select(doc => IndexAction.Create(doc)))));
}
Does anyone know why this error occurs?

The issue is because of an extra call to IndexAction.Create. If you change your indexing code to this, it will work:
indexClient.Documents.Index(IndexBatch.Create(documents.Select(doc => IndexAction.Create(doc))));
The compiler didn't catch this because IndexBatch.Create has a params argument that can take any number of IndexAction<T> for any type T. In this case, T was a collection, which is not supported (documents must be objects, not collections).
The programming model for creating batches and actions is changing substantially in the 1.0.0-preview release of the SDK. It will be more type-safe so that mistakes like this are more likely to be caught at compile-time.

Related

Can you use a Map instance as an easy-peasy store property?

ie.
const store = {
values: new Map(),
// (gross trivial accessor)
setValue: action( (state, payload) => {
state.values.set(payload.key, payload.value);
}
}
I'm curious because easy-peasy uses a Proxy on the store object (and objects nested within) so that in your action you can safely mutate the state object directly (https://easy-peasy.now.sh/docs/tutorials/primary-api.html#modifying-the-state). I don't know if this also works when using non Plain Old JavaScript Objects, such as Maps.
It looks like this is possible on certain versions, but not without first declaring support for the feature (so the code above will not work right out of the box, as of now). See here for more info: https://github.com/ctrlplusb/easy-peasy/issues/440

Make mongo stop throwing errors related to unsupported text index language

I have a text index on a collection. I added a language field to my documents, and all of a sudden started receiving a bunch of "language override unsupported: <LANG>" errors. Apparently language is a magical field when you have a text index.
How do I make mongo not throw an error if the language is unsupported?
It doesn't matter to me if a language is unsupported. I want my insert operation to succeed, regardless if the language is supported or not.
The insert operation:
// This should succeed regardless if suggestion.language is an unsupported language
// I don't want to wrap this in a try/catch, and have to retry on error.
addSuggestion (suggestion) {
const suggCol = db.get().collection('suggestions')
return suggCol.insertOne(suggestion)
},
How I create my index
// Create a text index, on the "text" property.
// TODO: Mongo throws error if suggestion.language contains an
// unsupported language. Override the language for now.
db.collection('suggestions').createIndex({ text: 'text' }, { language_override: 'dummyVal' })
To avoid the error for now, I'm ignoring the text index by setting { language_override: 'dummyVal' }. In the future, I would like to use the language_override.
This is a feature and you seem to have already arrived at the correct solution - language_override.

Is there a way to convert a graphql query string into a GraphQLResolveInfo object?

I have written a piece of software that parses and formats the fourth parameter of a graphql resolver function (the info object) to be used elsewhere. I would like to write unit tests for this software. Specifically, I do not want to build the GraphQLResolveInfo object myself, because doing that would be very cumbersome, error-prone and hard to maintain. Instead, I want to write human-readable query strings and convert them to GraphQLResolveInfo objects so I can pass those to my software.
After extensive googling and reading of the graphql-js source code, I have not found a simple way to do what they are doing internally. I'm really hoping that I am missing something.
What I am not trying to do is use the graphql-tag library, because that just generates an AST which has a very different format from the GraphQLResolveInfo type.
Has anyone done this before? Help would be much appreciated!
I will keep monitoring this question to see if a better answer comes along, but I've finally managed to solve my particular issue by creating as close an approximation of the GraphQLResolveInfo object as I need for my particular use case.
The GraphQLResolveInfo object is composed of several attributes, two of which are called fieldNodes and fragments. Both are in fact parts of the same AST that graphql-tag generates from a query string. These are the only parts of the GraphQLResolveInfo object that concern the software I wrote, the rest of it is ignored.
So here is what I did:
import gql from 'graphql-tag';
// The converter function
const convertQueryToResolveInfo = (query) => {
const operation = query.definitions
.find(({ kind }) => kind === 'OperationDefinition');
const fragments = query.definitions
.filter(({ kind }) => kind === 'FragmentDefinition')
.reduce((result, current) => ({
...result,
[current.name.value]: current,
}), {});
return {
fieldNodes: operation.selectionSet.selections,
fragments,
};
};
// An example call
const query = gql`
query {
foo {
bar
}
}
`;
const info = convertQueryToResolveInfo(query);
From the AST generated by graphql-tag, I extract and modify the operation and fragment definitions so that they look the way they do within the GraphQLResolveInfo object. This is by no means perfect and may be subject to change in the future depending on how my software evolves, but it is a relatively brief solution for my particular problem.

Mongoose idGetter error: Cannot set property '_id' of null

I am getting the following error from the Mongoose idGetter function. Can anyone shed some light on what may be causing it?
return this.$__._id = null == this._id
^
TypeError: Cannot set property '_id' of null
at model.idGetter (e:\Users\Christine\test\mvt\node_modules\mongoose\lib\schema.js:98:23)
The error situation involves multiple client requests performing document removes (on different documents in the same collection), on a database being accessed over internet (i.e. slow response time). The failure happens on accessing the id of one of the removed documents. There appears to be a small timing window in which it occurs - everything I've tried to debug it causes the problem to 'go away'.
Outline of the application code:
Details.findOneAndRemove({ _id : remove_id}, afterRemove);
function afterRemove(err, removedDoc){
if (!err && removedDoc){
OtherDetails.find({ _id: some_id}, afterFind);
}
function afterFind(err, foundDoc){
if (!err && foundDoc){
// next line causes exception
if (foundDoc.details_id === removedDoc.id) { // do stuff };
}
}
}
Do you have an id property defined on the document that you have removed?
If not, you should probably want to compare foundDoc.details_id with removedDoc._id
Below is the source code for the idGetter function in the mongoose code base:
function idGetter () {
if (this.$__._id) {
return this.$__._id;
}
return this.$__._id = null == this._id
? null
: String(this._id);
}
As I understand, I think that the idGetter is specifically aimed at ObjectId types, hence that exception.
You could also try to add an id property on the document if it does not yet exist to see if it continues to throw the same exception.
fwiw: it is possible that the problem was related to using 32-bit Node on 64-bit Windows (8.1). After installing 64-bit Node, I could not reproduce the problem.
Unsatisfying level of certainty, but I thought I would share in case anyone else gets a similar problem or can shed light on whether this might really have been the cause.

Cannot access properties on a populate()'d object from Mongoose?

This is very odd... I'm using populate() with a ref to fill in an array within my schema, but then the properties are inaccessible. In other words, the schema is like this:
new Model('User',{
'name': String,
'installations': [ {type: String, ref: 'Installations'} ],
'count': Number,
}
Of course, Insallations is another model.
Then I find & populate a set of users...
model.find({count: 0}).populate('installations').exec( function(e, d){
for(var k in d)
{
var user = d[k];
for(var i in user.installations)
{
console.log(user.installations[i]);
}
}
} );
So far so good! I see nice data printed out, like this:
{ runs: 49,
hardware: 'macbookpro10,1/x86_64',
mode: 'debug',
version: '0.1' }
However, if I try to actually ACCESS any of those properties, they're all undefined! For example, if I add another console log:
console.log(user.installations[i].mode);
Then I see "undefined" printed for this log.
If I try to operate on the object, like this:
Object.keys(user.installations[i]).forEach(function(key) { } );
Then I get a typical "[TypeError: Object.keys called on non-object]" error, indicating that user.installations[i] is not an object (even though it is outputted to the console as if it were). So, I even tried something ugly like...
var install = JSON.parse(JSON.stringify(user.installations[i]));
console.log(install, install.mode);
And, again, the first output (install) is a nice object containing the property 'mode'... but the 2nd output is undefined.
What gives?
Finally, I solved this...
I tried doing a console.log(typeof user.installations[i]); and got "string" as the output. This seemed odd, given that printing the object directly created console output (above) that looked like a normal object, not a string. So, I tried doing a JSON.parse(); on the object, but received the error "SyntaxError: Unexpected token r"
Finally, I realized what was going on. The "pretty console output" I described above was the result of a string formatted with \n (newlines). I had not expected that, for whatever reason. The JSON.parse() error is due to the fact that there is a known necessity with the node.js parser when attempting to parse object keys without quotations; see the SO question here:
Why does JSON.parse('{"key" : "value"}') do just fine but JSON.parse('{key : "value"}') doesn't? .
Specifically, note that the JSON parser in my case is failing on the character 'r', the fist character of "runs," which is the first key in my JSON string (above). At first I was afraid I needed to get a custom JSON parser, but then the problem hit me.
Look back to my original schema. I used a String-type to define the installation ref, because the array field was storing the installations's _id property as a String. I assume the .populate() field is converting the object to a String on output.
Finally, I looked at the Mongoose docs a little closer and realized I'm supposed to be referencing the objects based upon Schema.ObjectID. This explains everything, but certainly gives me some fixing to do in my schemas and code elsewhere...

Resources