Exact match option for gis.content.search

3569
6
09-24-2018 10:17 AM
Status: Open
MelanieWawryk
Occasional Contributor III

When trying to search and update content on AGOL there is only the option to search close matches and then somehow figure out if you have the correct one prior to updating the one from the list returned using gis.content.search.

There should be an option to search for an exact match and not bother with a list that is returned. If for example,  I want to update Traffic_Closures the search will return Traffic_Closures_Historic. You have to know ahead of time which result will show up first so you can tell the search to give you the first result or the second result. In this case, I want to update both layers so I can't just get rid of similarly named features to make sure my first result is always the correct result.

The use case is in https://www.esri.com/arcgis-blog/products/api-python/analytics/updating-your-hosted-feature-services... 

It will often find a similarly named layer rather than the one you asked for.

print("Search for original SD on portal…")
sdItem = gis.content.search("{} AND owner:{}".format(sd_fs_name, user), item_type="Service Definition")[0]
print("Found SD: {}, ID: {} n Uploading and overwriting…".format(sdItem.title, sdItem.id))
sdItem.update(data=sd)
print("Overwriting existing feature service…")
fs = sdItem.publish(overwrite=True)

You can improve the results by adding in title

sdItem = gis.content.search("title:{} AND owner:{}".format(sd_fs_name, user), item_type="Service Definition")[0]

but it still returns  Traffic_Closures_Historic as the first result when you search for Traffic_Closures

Please add a search that will return an exact match without having to get a list back.

6 Comments
MelanieWawryk

I even deleted the Historic layer and replaced it with one named HISTORIC_TRAFFIC_CLOSURES and TRAFFIC_CLOSSURES still finds the historic one as the first result.

Script:
sdItem = gis.content.search("title:{} AND owner:{}".format(sd_fs_name, user), item_type="Service Definition")[0]
print ("Search title:{} AND owner:{}".format(sd_fs_name, user))
print("Found SD: {}, ID: {} n Uploading and overwriting…".format(sdItem.title, sdItem.id))
sdItem.update(item_properties={'tags': itemtags, 'snippet': itemsummary, 'accessInformation': itemcredit}, data=sd, thumbnail=itemThumbnail)
fs = sdItem.publish(overwrite=True)

Results:
Search title:Traffic_Closures AND owner:KitchenerGIS
Found SD: Historic_Traffic_Closures, ID: ca7a9a21ab1d48bcbc750f21817604bf n Uploading and overwriting…
User cant overwrite this service, using this data, as this data is already referring to another service.
type error: User cant overwrite this service, using this data, as this data is already referring to another service.
(Error Code: 500)

Search title:Historic_Traffic_Closures AND owner:KitchenerGIS
Found SD: Historic_Traffic_Closures, ID: ca7a9a21ab1d48bcbc750f21817604bf n Uploading and overwriting…
Finished updating: Historic_Traffic_Closures – ID: 92cc3761a7c1401c8508bb4a2f2c9e35
Process completed at 09-26-2018 09:24:52 AM.

MelanieWawryk

We ended up adding a loop to look for an exact match. I still think you should be able to just have a search function return an exact match directly. 

# Find the SD, update it, publish /w overwrite and set sharing and metadata
print("Search for original SD on portal…")
#Check that it found the correct layer
match=0
layerno = 0
while (match == 0):
sdItem = gis.content.search(query="title:"+ sd_fs_name + " AND owner: " + user, item_type="Service Definition")[layerno]
foundlayer = sdItem.title
if foundlayer == sd_fs_name:
match = 1
print("Layer Returned: " + foundlayer + " vs " + sd_fs_name)
else:
match = 0
layerno = layerno + 1
print("Layer Returned: " + foundlayer + " vs " + sd_fs_name + " Index No: " + str(layerno))
#sdItem = gis.content.search("title:{} AND owner:{}".format(sd_fs_name, user), item_type="Service Definition")[0]
sdItem = gis.content.search(query="title:"+ sd_fs_name + " AND owner: " + user, item_type="Service Definition")[layerno]
print ("Search title:{} AND owner:{}".format(sd_fs_name, user))
print("Found SD: {}, ID: {} n Uploading and overwriting…".format(sdItem.title, sdItem.id))
sdItem.update(item_properties={'tags': itemtags, 'snippet': itemsummary, 'accessInformation': itemcredit}, data=sd, thumbnail=itemThumbnail)
print("Overwriting existing feature service...")
fs = sdItem.publish(overwrite=True)


if shrOrg or shrEveryone or shrGroups:
print("Setting sharing options…")
fs.share(org=shrOrg, everyone=shrEveryone, groups=shrGroups)
rundate=datetime.datetime.now()
print("Updated: {} – ID: {}".format(fs.title, fs.id)," at " + rundate.isoformat())

BoiseGIS

Another workaround option, also using "matching". 

query_string = 'title: ' + fs_title + ' AND owner: Boise_GIS'
search_results = gis.content.search(query=query_string, item_type='Feature Layer')

for item in search_results:
     item_title = item.title
     if item_title == fs_title:
         <do stuff here>

MollyWatson1

I've tried the exact match ideas suggested by Boise GIS and Melanie Wawryk and I still get an error: User cant overwrite this service, using this data, as this data is already referring to another service.  The script finds the correct feature service and service definition but it won't overwrite. 

PaulHoefflerGISS

Esri Technical Support reports:

ENH-000125277: Allow for exact matching of the query string used in the search function of the ArcGIS API for python. This Enhancement has been closed and is not in the current product plan.

The reasoning is that the search function is not designed for exact searching. See the documentation quoted below.
https://developers.arcgis.com/rest/users-groups-and-items/search-reference.htm
This search engine uses many different inputs to find the appropriate results and rank them. This often makes search 'fuzzy', making it ideal for human interaction, but not necessarily ideal for looking for specific records programmatically. Developers should avoid using search to find specific items (e.g. by title) as the results of these types of queries might change as the search engine evolves.

Since the Enhancement Request is closed and this ArcGIS Idea has a status of New after two years it doesn't appear that Esri is considering implementing this request. At least there are some work-arounds from users in this thread.

Brian_Wilson

When I was working on this same problem I did not find this thread until today.

I worked through a hack to do an exact search that seems to work just fine and it's only a couple of lines of python.  I posted it here.

https://community.esri.com/t5/arcgis-api-for-python-questions/gis-contentmanager-search-will-not-do-...

Of course, I wrote about using ArcGIS Enterprise not AGOL but I think it should work the same way.