Hi everyone I wanted to ask what is the best way to create a new user who has read and write privileges on a specific database.
I am trying with this but it doesn't work
var command = new BsonDocument
{
{"createUser", Mail.Text },
{"pwd", Password.Text },
{"roles", new BsonArray()
{
new BsonDocument
{
{"role", "readWrite"},
{"db", DenSociale.Text }
}
}
}
};
await db.RunCommandAsync<BsonDocument>(command);
return this error
MongoError: not authorized on (User) to execute command { createUser: "newuser", pwd: "xxx", roles: [ { role: "readWrite", db: "User" } ], lsid: { id: UUID("ce6c39d4-e14c-4f6c-b5d0-d66d210e9833") }, $clusterTime: { clusterTime: Timestamp(1622456008, 30), signature: { hash: BinData(0, F02EF0CAD605D9ECBCF3E928F84853FECE9B2829), keyId: 6968352101504122883 } }, $db: "(User)" }
Related
For example we have following document in elastic:
{
"name": "Bob",
"age": "22",
"phrase": "ohohoho",
"date": "2022-10-20T00:00:00Z"
}
string phrase ;
DateTime? date;
Then we want put following:
{
"name": "not Bob",
"age": "22",
"phrase": null,
"date": null
}
in c#:
var updateRequest = new UpdateRequest<T, T>(entity)
{
ScriptedUpsert = true,
Script = new InlineScript(
$"if (someCondition) {{ctx._source.putAll(params.entity);}} else {{ctx.op = \"noop\";}}")
{
Lang = "painless",
Params = new Dictionary<string, object>() { { "entity", entity } },
},
Upsert = Activator.CreateInstance<T>()
};
but in the end it will not update phrase and date.
It makes following request:
POST /myIndex/_update/b90278fd-1a66-40bf-b775-d076122c6c02
{
"script": {
"source": ""if (someCondition) {{ctx._source.putAll(params.entity);}} else {{ctx.op = \"noop\";}}"",
"lang": "painless",
"params": {
"entity": {
"name": "",
"age": 22
}
}
},
"upsert": {
"age": 0
}
}
Idk why but it skips all fields with null.
How to update nullable fields to null?
NEST does not support sending null values by default.
You can have a check in script such that if a value is not passed then you can remove it from document.
var updateRequest = new UpdateRequest<T, T(entity)
{
ScriptedUpsert = true,
Script = new InlineScript($"if (params.entity.phrase==null)ctx._source.remove('phrase');")
{
Lang = "painless",
Params = new Dictionary<string, object>() { { "entity", entity } },
},
Upsert = Activator.CreateInstance<T>()
};
You can check for more details here
I have the below mongoDB query working perfectly fine in mongoDB shell but wondering how to use that query in C#?
db.collection.aggregate([{
$match: {
fieldName: "dsdsd",
createdAt: {
$gte: ISODate("2021-07-05T12:29:30.000+00:00"),
$lte: ISODate("2021-07-15T12:29:30.000+00:00")
}
}
}, {
$group: {
_id: {
$dateToString: {
format: "%Y-%m-%d-%H",
date: "$createdAt"
}
},
items: {
$first: '$$ROOT'
}
}
},{"$replaceRoot":{"newRoot":"$items"}}
,{"$sort":{"createdAt":-1}}
])
I want to use the below raw query in c# something like below:
var pipeline = {
$match: {
fieldName: "dsdsd",
createdAt: {
$gte: ISODate("2021-07-05T12:29:30.000+00:00"),
$lte: ISODate("2021-07-15T12:29:30.000+00:00")
}
}
}, {
$group: {
_id: {
$dateToString: {
format: "%Y-%m-%d-%H",
date: "$createdAt"
}
},
items: {
$first: '$$ROOT'
}
}
},{"$replaceRoot":{"newRoot":"$items"}}
,{"$sort":{"createdAt":-1}}
var result = await _mongoDbContext.model.Aggregate(pipeline).ToListAsync();
you can add any custom stage via AppenStage
collection
.Aggregate()
.AppendStage<BsonDocument>(BsonDocument.Parse("stage1"))
.AppendStage<BsonDocument>(BsonDocument.Parse("stage2"))
..
or
var pipeline = new EmptyPipelineDefinition<BsonDocument>()
.AppendStage<BsonDocument, BsonDocument, BsonDocument>(BsonDocument.Parse("stage1"))
.AppendStage<BsonDocument, BsonDocument, BsonDocument>(BsonDocument.Parse("stage2"));
collection.Aggregate(pipeline).ToList();
UPDATE:
you can also use a shell-like syntax for db.runCommand (which is harder):
MongoDB Enterprise mongos> db.runCommand({ aggregate: 'test', pipeline: [ {stage1_json}, {stage2_json} ], cursor: {} })
...
where the c# equivalent is:
var result = db.RunCommand<BsonDocument>("{ aggregate : 'test', pipeline: [ {stage1_json}, {stage2_json} ], cursor: {} }");
I have created a LUIS Template Bot Application (Version 3) and I need to capture the output of an Adaptive Card drop down list. I am currently able to create and render the drop down list but facing difficulty capturing the result once the button is clicked. Can you please give me a solution or give link to appropriate tutorial for version 3 as resources for this issue is mostly for version 4.
public Attachment PolicyAdaptiveCard()
{
var card = new AdaptiveCard();
var choices = new List<AdaptiveChoice>();
choices.Add(new AdaptiveChoice()
{
Title = "Category 1",
Value = "c1"
});
choices.Add(new AdaptiveChoice()
{
Title = "Category 2",
Value = "c2"
});
var choiceSet = new AdaptiveChoiceSetInput()
{
IsMultiSelect = false,
Choices = choices,
Style = AdaptiveChoiceInputStyle.Compact,
Id = "Category"
};
card.Body.Add(choiceSet);
card.Actions.Add(new AdaptiveSubmitAction() { Title = "Select Category", Data = Newtonsoft.Json.Linq.JObject.FromObject(new { button = "select" }) });
Attachment attachment = new Attachment()
{
ContentType = AdaptiveCard.ContentType,
Content = card,
Name = $"Card"
};
return attachment;
}
This is JSON output that I am capturing in Bot Emmulator
{
"channelData": {
"clientActivityID": "15547009411880.yfus2yy2mao",
"postBack": true
},
"channelId": "emulator",
"conversation": {
"id": "3f50f7c1-59be-11e9-98bd-17dcaa70e8d3|livechat"
},
"from": {
"id": "r_tckd4zoa8h",
"name": "User",
"role": "user"
},
"id": "48d27080-59be-11e9-93ff-a77a4eb2d000",
"localTimestamp": "2019-04-08T08:22:21+03:00",
"locale": "en-US",
"recipient": {
"id": "97e06f60-496a-11e9-9541-3d37a55e03cc",
"name": "Bot",
"role": "bot"
},
"serviceUrl": "http://localhost:56373",
"showInInspector": true,
"timestamp": "2019-04-08T05:22:21.192Z",
"type": "message",
"value": {
"Category": "c1",
"button": "select"
}
}
How can I read the value and output "c1" in the next method ? This is the code that I am following. Can you please give me the method I can use to capture the category value
var reply = context.MakeMessage();
var activityValue = context.Activity.AsMessageActivity().Value as Newtonsoft.Json.Linq.JObject;
if (activityValue != null)
{
var categorySelection = activityValue.ToObject<CategorySelection>();
var category = categorySelection.Category;
await context.PostAsync(reply);
}
For bot framework v3 you could do something like this as your callback function:
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
if (activity.Value != null)
{
dynamic value = activity.Value;
var category = value.Category;
await context.PostAsync(category);
}
context.Wait(MessageReceivedAsync);
}
Using dynamics it's very easy to access the values. Simply register this message as callback function on context.Wait in your initial prompt where you send your adaptive card.
If you would like to have a more typed version, you could model the result of you card and parse it like this:
private static string GetTypedCategoryFromAdaptiveCard(Activity activity)
{
var content = JsonConvert.DeserializeObject<CategoryResponse>(activity.Value.ToString());
return content.Category;
}
public class CategoryResponse
{
public string Category { get; set; }
}
I am trying to use c# to insert each new subdocument into an array at the top position using driver version 2.4.2.
In mongo the following command works well:
db.getCollection('Operation').update(
{_id: ObjectId('586e9ec5ab3d05173cd88957') },
{$push: {'location': {$each: [ { 'value' : 'Site', 'time' : ISODate('2017-02-24T16:05:44.204Z'), 'user' : 'user1' } ], $position: 0 } } }
)
Then the result is:
{
"_id" : ObjectId("586e9ec5ab3d05173cd88957"),
"location" : [
{
"value" : "Site",
"time" : ISODate("2017-02-24T16:05:44.204Z"),
"user" : "user1"
}
]
}
But so far I do not succeed in getting the same result in C#. I have tried so far:
var filter = Builders<BsonDocument>.Filter.Eq("_id", ObjectId.Parse("586e9ec5ab3d05173cd88957"));
var update = Builders<BsonDocument>.Update.PushEach("location", new List<BsonArray>() { new BsonArray { new BsonDocument { { "value", "Site" }, { "time", DateTime.UtcNow }, { "user", "user1" } } } }, position: 0);
collection.UpdateOne(filter, update);
And also no succes trying to specify all in text:
collection.UpdateOne("{ '_id': ObjectId('586e9ec5ab3d05173cd88957') }", "{ '$push': {'location': { '$each': [ { 'value' : 'Site', 'time' : ISODate('2017-02-24T16:05:44.204Z'), 'user' : 'user1' } ], $position: 0 } } }");
Any suggestions?
PushEach expects just a BsonArray parameter, not a List<BsonArray>.
You should be doing something like
var update = updateBuilder.PushEach("location", locationBSONArray);
There is no need to serialize to bson document.
Took me a while because of a typo. The answer of user1892538 was correct. This works:
var update = Builders<BsonDocument>.Update.PushEach("location", new BsonArray { new BsonDocument { { "value", "Site" }, { "time", DateTime.UtcNow }, { "user", "user1" } } }, position: 0);
I'm new to MongoDB and, after some tutorials, I'm trying to read data from my SQL Server database and reverse them in MongoDB, with C# and Entity Framework.
I found this code on MongoDB site:
async static void addDoc()
{
var document = new BsonDocument
{
{ "address" , new BsonDocument
{
{ "street", "2 Avenue" },
{ "zipcode", "10075" },
{ "building", "1480" },
{ "coord", new BsonArray { 73.9557413, 40.7720266 } }
}
},
{ "borough", "Manhattan" },
{ "cuisine", "Italian" },
{ "grades", new BsonArray
{
new BsonDocument
{
{ "date", new DateTime(2014, 10, 1, 0, 0, 0, DateTimeKind.Utc) },
{ "grade", "A" },
{ "score", 11 }
},
new BsonDocument
{
{ "date", new DateTime(2014, 1, 6, 0, 0, 0, DateTimeKind.Utc) },
{ "grade", "B" },
{ "score", 17 }
}
}
},
{ "name", "Vella" },
{ "restaurant_id", "41704620" }
};
var collection = _database.GetCollection<BsonDocument>("restaurants");
await collection.InsertOneAsync(document);
}
It works as I expect. So, I made this:
using (var db = new Entities())
{
foreach (var trans in db.TRANSACTIONS)
{
try
{
var document = new BsonDocument
{
{ "ID", erog.ID.ToBson() },
{ "CUSTOMER" , new BsonDocument
{
{ "CSTID", trans.CUSTOMERS.CSTID.ToBson() },
{ "NAME", trans.CUSTOMERS.NAME.ToBson()},
{ "CITY", trans.CUSTOMERS.CITY.ToBson() },
{ "ZIP", trans.CUSTOMERS.ZIP.ToBson() },
{ "STATE", trans.CUSTOMERS.STATE.ToBson() },
}
},
{ "TRANSACTIONNUMBER", trans.TRANSACTIONNUMBER.ToBson() },
{ "TIMESTAMP", erog.TIMESTAMP.ToBson() },
{ "AMOUNT", erog.AMOUNT.ToBson() },
{ "PAYMENT", erog.PAYMENT.ToBson() },
};
var collection = _database.GetCollection<BsonDocument>("transactions");
collection.InsertOne(document);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
When I try to execute this code, I get an error when executing var document = new BsonDocument {....}; the error is "A string value cannot be written to the root level of a bson document". So, as you can see, I tried to put the .ToBson() at the end of my values, but the result is still the same.
The only difference is the value isn't a string between two quotation marks, but it is a real value from my table.
How can I reach my goal and create&insert a document in my MongoDB database, starting from my code above?
Ok, dumb question, dumb solution.
Just replace all toBson() with toString() and now it works! :)