Forgive me if this is redundant or I'm missing something simple, but I'm playing around with ElasticSearch (and NEST in particular) to see if it would be a good add for our b2b ecommerce site's search function.
I grabbed the latest NuGet of NEST and then tried to serialize and add something to an index. Here is a snippet of the approach I was using
var localhost = new Uri("http://localhost/9200");
var setting = new ConnectionSettings(localhost).SetDefaultIndex("cpi_catalog");
var client = new ElasticClient(setting);
client.MapFromAttributes<Item>();
var testitem = new Item()
{
Description = "test",
Id = 9999999,
Manufacturer_Id = 5,
Quantity_Per_Unit = 1,
Quantity_Unit_Id = "EA",
SKU = "AVE29845",
Subtitle = "test",
Title = "test"
};
var status = client.Index(testitem);
However, it seems that testitem is never indexed at all, when I do a GET for /cpi_catalog/items/9999999 I get the following:
{"_index":"cpi_catalog","_type":"items","_id":"9999999","exists":false}
What seemingly simple thing am I missing here?
EDIT: When debugging, I get back a Nest.IndexResponse with all fields NULL besides status.OK which is false
Seems like the uri is has a typo:
var localhost = new Uri("http://localhost/9200");
should probably be:
var localhost = new Uri("http://localhost:9200");
Related
I am trying to send data to Elasticsearch from .Net by using NEST library.
My ES version is 6.7 and NEST version 6.7 too.
So while creating index I get exception type query_shard_exception No mapping found for [#timestamp] in order to sort on
I created single node and tried send my message.
var node = new Uri("http://localhost:9200/");
var mysettings = new ConnectionSettings(node);
var client = new ElasticClient(mysettings);
var tweet = new {
Id = 1,
FirstName = "John",
LastName = "Grank",
PostDate = new DateTime(2019,7,12),
Message = "Trying out NEST, so far so good?"
}
var response = client.Index(tweet,idx=> idx.Index(mytweetindex));
Do you have any idea what I did wrong? Thanks.
I'm trying to port over JavaScript code that interacts with a MongoDb to C# .NET and having problems with a delete/pull operation. I can't seem to figure out how to iterate over the Ponies array and remove a single ObjectId by matching to a passed in ObjectId.
{
"_id" : ObjectId("388e8a66fe2af4e35c60e"),
"Location" : "rainbowland",
"Ponies" : [
ObjectId("388e8a66fe2af4e35c24e83c"),
ObjectId("388e8a66fe2af4e35c24e860"),
ObjectId("388e8a66fe2af4e35c24e83d")
]
}
I've tried several different ways based on what I've found online but nothing seems to work. When I check the collection to see if 388e8a66fe2af4e35c24e860 was removed from the Ponies array I see that it wasn't removed. Everytime I execute the code and look at the ModifiedCount for resultPonies it shows zero. Two examples of what I've tried doing are below.
var pony = new Pony() { Id = new ObjectId("388e8a66fe2af4e35c24e860") }
var pullPonies = Builders<Ranch>.Update.PullFilter(x => x.Ponies,
y => y.Id == pony.Id);
var filterPonies = Builders<Ranch>.Filter.Where(x => true);
var resultPonies = _context.Ranches.UpdateMany(filterPonies, pullPonies);
OR
var pullPonies = Builders<BsonDocument>.Update.PullFilter("Ponies",
Builders<ObjectId>.Filter.Eq("ObjectId", pony.Id));
var filterPonies = Builders<BsonDocument>.Filter.Where(x => true);
var resultPonies = _context.Ranches.UpdateMany(filterPonies, pullPonies);
Here is the JavaScript code that I believe works but haven't been able to test yet.
db.collection("Ranches").update({}, {$pull: {Ponies: pony._id}}, {multi: true});
Ok, I found a solution for the problem. Since I'm not actually going to be filtering within the array of objects, they are all ObjectIds in a BsonArray, I need to find where the value in the array matches the given ObjectId. In those cases the array item should be pulled out. If the object in the array had other properties then I would probably want to use the PullFilter. But in this case I don't need to filter the additional level. That is at least what I believe I was doing wrong. Here are the solutions
var ponyId = new ObjectId("388e8a66fe2af4e35c24e860");
var pullPonies = Builders<Ranch>.Update.Pull(x => x.Ponies, ponyId);
// This line is to retrieve all Ranch objects in the collection
var filterPonies = Builders<Ranch>.Filter.Where(x => true);
var resultPonies = _context.Ranches.UpdateMany(filterPonies, pullPonies);
Or
var ponyId = new ObjectId("388e8a66fe2af4e35c24e860");
var pullPonies = Builders<BsonDocument>.Update.Pull("Ponies", ponyId));
// This line is to retrieve all Ranch objects in the collection
var filterPonies = Builders<BsonDocument>.Filter.Where(x => true);
var resultPonies = _context.Ranches.UpdateMany(filterPonies, pullPonies);
I'm using the RetrieveEntityRequest to get an entity's attributes' metadata:
RetrieveEntityRequest entityRequest = new RetrieveEntityRequest
{
EntityFilters = EntityFilters.Attributes,
LogicalName = joinedEntityName.Value,
};
RetrieveEntityResponse joinedEntityMetadata = (RetrieveEntityResponse)_service.Execute(entityRequest);
Now, consider I need to execute this request for multiple entities. Is it possible to do this in one execution (maybe not with RetrieveEntityRequest), instead of one request for each entity?
You can't do it with RetrieveEntityRequest. However, you can do a RetrieveMetadataChangesRequest to get what you want. It's misleadingly named for your purposes, but if you don't provide a ClientVersionStamp property, it will simply retrieve everything you've specified in the Query property.
Here's a simple example where you'd retrieve the metadata for account and contact, and only retrieve the LogicalName and DisplayName properties:
var customFilterExpression = new[]
{
new MetadataConditionExpression("LogicalName", MetadataConditionOperator.Equals, "account"),
new MetadataConditionExpression("LogicalName", MetadataConditionOperator.Equals, "contact")
};
var customFilter = new MetadataFilterExpression(LogicalOperator.Or);
customFilter.Conditions.AddRange(customFilterExpression);
var entityProperties = new MetadataPropertiesExpression
{
AllProperties = false
};
entityProperties.PropertyNames.AddRange("LogicalName", "DisplayName");
var request = new RetrieveMetadataChangesRequest
{
Query = new EntityQueryExpression
{
Properties = entityProperties,
Criteria = customFilter,
}
};
This method also has the benefit of only retrieving what specific properties you need, which makes the request faster and the payload smaller. It's specifically designed for mobile where you want to only retrieve the Metadata you need, and what has changed since the last time you retrieved it, but it works nicely in a lot of scenarios.
You have to use RetrieveAllEntitiesRequest. Sample below:
RetrieveAllEntitiesRequest retrieveAllEntityRequest = new RetrieveAllEntitiesRequest
{
RetrieveAsIfPublished = true,
EntityFilters = EntityFilters.Attributes
};
RetrieveAllEntitiesResponse retrieveAllEntityResponse = (RetrieveAllEntitiesResponse)serviceProxy.Execute(retrieveAllEntityRequest);
CRM SDK has all or one-by-one approach only.
You have to keep your list of entities ready & issue the RetrieveEntityRequest for each item.
WSDL 2014.2. C# in Visual Studio 2013.
I can get "Inventory Item" items using this code:
var recordRefs = new List<RecordRef>();
foreach (string externalId in ExternalIds)
{
recordRefs.Add(new RecordRef
{
externalId = externalId,
type = RecordType.inventoryItem,
typeSpecified = true
});
}
var request = new ItemSearchBasic
{
externalId = new SearchMultiSelectField
{
#operator = SearchMultiSelectFieldOperator.anyOf,
operatorSpecified = true,
searchValue = recordRefs.ToArray()
}
};
SearchResult response = SuiteTalkConnection.Service.search(request);
However, if I change type = RecordType.inventoryItem to type = RecordType.lotNumberedAssemblyItem then I don't get results. I am specifying correct values as external IDs.
I have tried all sorts of variations on the above, including ItemSearch instead of ItemSearchBasic but I never get results.
It doesn't help that I can find zero NetSuite documentation on searching for specific item types.
I think answer to this question would also work in this case. Try using type as "assemblyItem" only and use an additional searchFilter "isLotItem" and set it to true.
Cannot find any documentation for this...
Currently using the following code to get a list of my photos:
FacebookApp fb = new FacebookApp(accessToken);
dynamic test = fb.Get("me/photos");
I'm cycling through the first 25 photos that it returns. Simple.
Now how do it get it to return the next 25?
So far I've tried this:
FacebookApp fb = new FacebookApp(accessToken);
string query = "me/photos";
while (true)
{
dynamic test = fb.Get(query);
foreach (dynamic each in test.data)
{
// do something here
}
query = test.paging.next;
}
but it fails throwing:
Could not parse '2010-08-30T17%3A58%3A56%2B0000' into a date or time.
Do I have to use a fresh dynamic variable for every request, or am I going about this the wrong way completely?
Ended up finding this:
// first set (1-25)
var parameters = new ExpandoObject();
parameters.limit = 25;
parameters.offset = 0;
app.Api("me/friends", parameters);
// next set (26-50)
var parameters = new ExpandoObject();
parameters.limit = 25;
parameters.offset = 25;
app.Api("me/friends", parameters);
I also found you can use this.
// for the first 25 albums (in this case) 1-25
dynamic albums = client.Get("me/albums", new { limit = "25", offset = "0"});
// for the next 25 albums, 26-50
dynamic albums = client.Get("me/albums", new { limit = "25", offset = "25"});
Worked the same as you used above.