Cannot get documentid using pnp.sp.search in spfx app - sharepoint

In an older JavaScript app I used keyword-query to search for document properties, and I could add the 'DlcDocID' field (Document id) to be retrieved.
I am currently developing an Spfx version of the app, and use pnp.sp.search to get document data. This way I can get the UniqueId and the DocId, but not the Document Id. How can I have this parameter included in the search results?
Extra:
I am using 1.3.11, and this code
pnp.sp.search(
{
Querytext:query,
RowLimit:rows,
StartRow:start,
SelectProperties: ["DocId"
, "UniqueId"
,"FileType"
,"ServerRedirectedEmbedURL"
, "ServerRedirectedPreviewURL"
,"LastModifiedTime"
,"Write"
,"Size"
,"SPWebUrl"
,"ParentLink"
,"Title"
,"HitHighlightedSummary"
,"Path"
,"Author"
,"LastModifiedTime"
,"DlcDocID"
],
But DlcDocID is never retrieved.

Looking at the docs, DlcDocID should be retrievable (it's queryable and retrievable by default). Have you tried using SearchQueryBuilder and selectProperties?
const q = SearchQueryBuilder().text(yourQuery).
.rowLimit(10).processPersonalFavorites.selectProperties('*', 'DlcDocID');
const results = await sp.search(q);
SearchQueryBuilder reference

The issue was that the pnp
SearchResult interface didn't have the DlcDocID in this version. Adding it solved the problem.

Related

Facebook marketing API: How to get the optimization event

Using the NodeJs (and also the REST API) Facebook marketing API I'm trying to know which Ad Sets are optimizing which event (e,g, add_to_wishlist)
To do that I'm fetching all ad sets:
import bizSdk = require('facebook-nodejs-business-sdk'); // v8.0.0
bizSdk.FacebookAdsApi.init('myaccesstoken')
const adAccount = new bizSdk.AdAccount('act_XXXXX');
const adSets= await adAccount.getAdSets([bizSdk.AdSet.Fields.optimization_sub_event,bizSdk.AdSet.Fields.optimization_goal]);
I always get NONE for the optimization_sub_event field and VALUE or OFFSITE_CONVERSIONS for optimization_goal
More over, I tried to fetch ALL fields possible and look for my event names but without success.
Is there away to achieve that using the API?
Fetch the field promoted_object.
The value for a custom event will have this structure:
promoted_object: {
"application_id": "994*******818",
"custom_event_type": "OTHER",
"object_store_url": "http://play.google.com/store/apps/details?id=com.*****",
"custom_event_str": "my_custom_event_name" // this is what you want
}

Retrieve Documents from a Template

I created a template within my DocuSign developer Sandbox that contains one document. I'm using the C# SDK to try and send out an envelope to a user, based on a template.
Here's the code where I retrieve all of the templates.
TemplatesApi templateApi = new TemplatesApi(ApiClient.Configuration);
EnvelopeTemplateResults templateResults = templateApi.ListTemplates(AccountID);
The issue I am having is the EnvelopeTemplateResults does NOT have any documents associated with it.
When I use the REST API using POSTMAN, performing a GET to this URL, I can see that there's an envelopeTemplateDefinition, that has a Document on it, which is the one I want.
My question is, how, using the SDK API, can I get the envelopeTemplateDefinition ?
In order to have the ListTemplates method include the Documents info, you have to set an Include parameter:
var templatesApi = new TemplatesApi(apiClient.Configuration);
var listTemplatesOptions = new TemplatesApi.ListTemplatesOptions { include = "documents" };
var templateResults = templatesApi.ListTemplates(accountId, listTemplatesOptions);
If you are trying to get the Template Definition of a single template, the templatesApi.Get() method can be used with its own set of Include options:
var getTemplateOptions = new TemplatesApi.GetOptions { include = "documents" };
var templateDefinition = templatesApi.Get(accountId, templateId, getTemplateOptions);
Finally, if you're trying to get an actual PDF out of a specific template, that would be the templatesApi.GetDocument() method:
templatesApi.GetDocument(accountId, templateId, documentId);
Where DocumentId is the specific document you want to pull, or "Combined" if you want to pull all the documents in as a single PDF.
Chris, if you are using the v2 API, there's an endpoint:
GET /v2/accounts/{accountId}/templates/{templateId}/documents/{documentId}
you can try it here - https://apiexplorer.docusign.com/#/esign/restapi?categories=Templates&tags=TemplateDocuments&operations=get
the c# SDK inside TemplateAPI has GetDocument() and UpdateDocument() methods

How to get Project Guid and Model Guid from PathName?

My Revit model has an RVT link with a PathName = "BIM 360://Testing Link Edit in BIM360/ArchitectureBIM360.rvt"
I want to construct a ModelPath and use it to open the cloud-hosted file as follows:
ModelPath mp = ModelPathUtils.ConvertCloudGUIDsToCloudPath(projectId, modelId);
linkDoc = uiapp.OpenAndActivateDocument(mp, new OpenOptions(), false, new cloudCallback()).Document;
How do I get the projectId and modelId GUIDs from the PathName?
Using Forge Data Management API you can list Hubs > Projects > Folders > Items > Versions. An item is essentially a file, but it can have 1+ versions, so that's why you need the specific version. This tutorial guides you on the steps.
Once you list version of an item, it should be an array under .data, each entry on the array should have something like (simplified):
{
"type":"versions",
"id":"urn:adsk.wipprod:fs.file:vf.abcd1234?version=1",
"attributes":{
"name":"fileName.rvt",
"displayName":"fileName.rvt",
...
"mimeType":"application/vnd.autodesk.r360",
"storageSize":123456,
"fileType":"rvt",
"extension":{
"type":"versions:autodesk.bim360:C4RModel",
....
"data":{
...
"projectGuid":"48da72af-3aa6-4b76-866b-c11bb3d53883",
....
"modelGuid":"e666fa30-9808-42f4-a05b-8cb8da576fe9",
....
}
}
},
....
}
Update
From the comment, on Revit desktop, you can use:
ModelPath path = doc.GetCloudModelPath();
Guid guid1 = path.GetModelGUID();
Guid guid2 = path.GetProjectGUID();
I'm not using the Forge API yet (I really need to go through the tutorial myself). I do not know if this would help in anyway or if you found the answer you were looking for but the cache folder does contain all the file and project GUIDs including links: "C:\Users\username\AppData\Local\Autodesk\Revit\Autodesk Revit 2019\CollaborationCache\2008062704538XX\4680d561-ed69-4a61-b9b2-587582b1627a\LinkedModels\1f96b01e-640e-4e16-93af-edcc11769570.rvt"
In the below path:
C:\Users\username\AppData\Local\Autodesk\Revit\Autodesk Revit 2019\CollaborationCache\2008062704538XX\4680d561-ed69-4a61-b9b2-587582b1627a\LinkedModels\1f96b01e-640e-4e16-93af-edcc11769570.rvt"
2008062704538XX is the oxygen ID which is a unique ID and it is linked to your Autodesk account.
4680d561-ed69-4a61-b9b2-587582b1627a is the GUID of the Project.
1f96b01e-640e-4e16-93af-edcc11769570 is the GUID of the linked model.

MongoDB update object and remove properties?

I have been searching for hours, but I cannot find anything about this.
Situation:
Backend, existing of NodeJS + Express + Mongoose (+ MongoDB ofcourse).
Frontend retrieves object from the Backend.
Frontend makes some changes (adds/updates/removes some attributes).
Now I use mongoose: PersonModel.findByIdAndUpdate(id, updatedPersonObject);
Result: added properties are added. Updated properties are updated. Removed properties... are still there!
Now I've been searching for an elegant way to solve this, but the best I could come up with is something like:
var properties = Object.keys(PersonModel.schema.paths);
for (var i = 0, len = properties.length; i < len; i++) {
// explicitly remove values that are not in the update
var property = properties[i];
if (typeof(updatedPersonObject[property]) === 'undefined') {
// Mongoose does not like it if I remove the _id property
if (property !== '_id') {
oldPersonDocument[property] = undefined;
}
}
}
oldPersonDocument.save(function() {
PersonModel.findByIdAndUpdate(id, updatedPersonObject);
});
(I did not even include trivial code to fetch the old document).
I have to write this for every Object I want to update. I find it hard to believe that this is the best way to handle this. Any suggestions anyone?
Edit:
Another workaround I found: to unset a value in MongoDB you have to set it to undefined.
If I set this value in the frontend, it is lost in the REST-call. So I set it to null in the frontend, and then in the backend I convert all null-values to undefined.
Still ugly though. There must be a better way.
You could use replaceOne() if you want to know how many documents matched your filter condition and how many were changed (I believe it only changes one document, so this may not be useful to know). Docs: https://mongoosejs.com/docs/api/model.html#model_Model.replaceOne
Or you could use findOneAndReplace if you want to see the document. I don't know if it is the old doc or the new doc that is passed to the callback; the docs say Finds a matching document, replaces it with the provided doc, and passes the returned doc to the callback., but you could test that on your own. Docs: https://mongoosejs.com/docs/api.html#model_Model.findOneAndReplace
So, instead of:
PersonModel.findByIdAndUpdate(id, updatedPersonObject);, you could do:
PersonModel.replaceOne({ _id: id }, updatedPersonObject);
As long as you have all the properties you want on the object you will use to replace the old doc, you should be good to go.
Also really struggling with this but I don't think your solution is too bad. Our setup is frontend -> update function backend -> sanitize users input -> save in db. For the sanitization part, we use a helper function where we integrate your approach.
private static patchModel(dbDocToUpdate: IModel, dataFromUser: Record<string, any>): IModel {
const sanitized = {};
const properties = Object.keys(PersonModel.schema.paths);
for (const key of properties) {
if (key in dbDocToUpdate) {
sanitized[key] = data[key];
}
}
Object.assign(dbDocToUpdate, sanitized);
return dbDocToUpdate;
}
That works smoothly and sets the values to undefined. Hence, they get removed from the document in the db.
The only problem that remains for us is that we wanted to allow partial updates. With that solution that's not possible and you always have to send everything to the backend.
EDIT
Another workaround we found is setting the property to an empty string in the frontend. Mongo then also removes the property in the database

ElasticSearch Field boosting using java api

I am new to ES and trying to search using java apis. I am unable to figure out how I can provide filed specific boosting using the java apis.
Here is the example:
My index document looks like:
_source": {
"th_id": 1,
"th_name": "test name",
"th_description": "test desc",
"th_image": "test-img",
"th_slug": "Make-Me-Smart",
"th_show_title": "Coast Tech Podcast",
"th_sh_category": "Alternative Health
}
When i search for keywords I want to boost the results higher if they found in the "th_name" compared to they're found in some other fields.
Currently I am using below code to do search:
QueryBuilder qb1 = QueryBuilders.multiMatchQuery(keyword, "th_name", "th_description", "th_show_title", "th_sh_category");
SearchResponse response = client.prepareSearch("talk").setTypes("themes")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setQuery(qb1)
.setFrom(start).setSize(maxRows)
.setExplain(true).execute().actionGet();
Is there anything I can do at query time to boost the document if the keyword is found in "th_name" field compared to found in other fields?
The accepted answer did not work me. ES version I am using is 6.2.4.
QueryBuilders.multiMatchQuery(keyword)
.field("th_name" ,2.0f)
.field("th_description")
.field("th_show_title")
.field("content")
Hope it helps someone else.
Edit: This has changed and does no longer work in ES 6.x and upwards.
You should also be able to boost a field directly in the Multi-match query:
"The multi_match query supports field boosting via ^ notation in the fields json field.
{
"multi_match" : {
"query" : "this is a test",
"fields" : [ "subject^2", "message" ]
}
}
In the above example hits in the subject field are 2 times more important than in the message field."
In the java-api, just use the MultiMatchQueryBuilder:
MultiMatchQueryBuilder builder =
new MultiMatchQueryBuilder( keyword, "th_name^2", "th_description", "th_show_title", "th_sh_category" );
Disclaimer: Not tested
You can use "BoostingQuery"
http://www.elasticsearch.org/guide/reference/query-dsl/boosting-query.html
javadoc : https://github.com/elasticsearch/elasticsearch/blob/master/src/main/java/org/elasticsearch/index/query/BoostingQueryBuilder.java

Resources