Umbraco 8 Examine/Lucene query returns no results in code but searching from the backoffice works as expected - lucene.net

I'm trying to do a simple Lucene query in a fresh Umbraco 8 site (8.13.0, Examine 1.1, Lucene.Net 3.0.3).
I'm trying to get all documents of a specific type but I get no results back.
ExamineManager.Instance.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out var index);
var searcher = index.GetSearcher();
var query = searcher.CreateQuery()
.NodeTypeAlias(BlogPost.ModelTypeAlias);
var result = query.Execute();
var rawQuery = query.ToString(); // == "{ Category: , LuceneQuery: +__NodeTypeAlias:blogpost }"
// result.Results.Count == 0
// result.TotalItemCount == 3
// result.TopDocs.TotalHits == 3
If I take the raw Lucene query +__NodeTypeAlias:blogpost and stick it in the search field in Examine Management in Umbraco I get 3 results as expected:
Why isn't it working from code? (What am I doing wrong?)

Related

Looping Over a Java Object and Passing One Field to a Mongo Query Similar to SQL WHERE...IN Clause

I am trying to construct a MongoDB equivalent of an SQL WHERE IN clause by iterating over a Java Object List and using one field in that list to fill in the IN data. Using generic example, I would like to build the following command in MongoDB syntax:
SELECT title FROM albums WHERE recorded_year IN ('1967','1968','1969','1970');
The SQL command IN data is extracted from the Album object recordedYear value using the following loop:
if (albums.size() <= 1000) {
sb.append("SELECT title FROM albums WHERE recorded_year");
sb.append(" IN (");
for (int i = 0; i < albums.size(); i++) {
sb.append("'");
sb.append(albums.get(i).getRecordedYear());
sb.append("'");
if (i < albums.size() - 1) {
sb.append(",");
} else {
sb.append(")");
}
}
}
Most Mongo/Java sites I visited seem to deal with command structures using hard-coded values which, while helpful, is completely impractical in real world applications. Any help in pointing to a good tutorial, or if someone has the actual code itself would be greatly appreciated.
Thanks.
But the issue I am having is understanding how to pass a Java Object
list to the to the getAllDocuments...
Make an array of elements which you want to match with the field using the in operator. For example, If you have a someObject.year field, then the array will have the year values; int [] matchYears = { 1989, 2001, 2012 }. Instead of an array you can also use a List collection.
The query:
Bson queryFilter = in("recordedYear", matchYears);
List<Document> result = new ArrayList<>();
collection.find(queryFilter).into(result);
result.forEach(System.out::println);
The queryFilter is built using the com.mongodb.client.model.Filters factory class.
The MongoDB documentation on using the $in operator.
NOTE: The int [] matchYears = { 1989, 2001, 2012 } can be also be created as
int [] matchYears = { javaObject1.recorded_year, javaObject2.recorded_year, ... }.
I didn't quite implement it with BSON, but the logic in the method appears to be working with the code below. Thank you again for your help.
public void getAlbumYears(MongoCollection<Document> collection, List<Album> albums) {
BasicDBObject inQuery = new BasicDBObject();
List<String> year = new ArrayList<>();
for(Album album : albums) {
year.add(album.getYear());
}
inQuery.put("year", new BasicDBObject("$in", year));
for (Document document : collection.find(inQuery)) {
System.out.println(document.toJson());
}
}

MongoDB : How to find multiple documents and update at the same time?

I have mongo DB and I am using C#.Net to interact with mongo db. C# API has methods for finding a single document and updating it at the same time. For example FindOneAndUpdateAsync.
However I couldn't find any method to find multiple documents and update them at the same time asynchronously.
The code below finding and processing each document asynchronously. How do I also update that document at the same time?
public async Task<IList<IDictionary<string, string>>> DoWork()
{
var collection = _mongoDatabase.GetCollection<BsonDocument>("units");
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Ne<string>("status", "INIT") &
(filterBuilder.Exists("isDone", false) |
filterBuilder.Eq<bool>("isDone", false));
// I want to pass this update filter to update the document. But not sure how
var update = Builders<BsonDocument>.Update
.CurrentDate("startTime");
var sort = Builders<BsonDocument>.Sort.Ascending("startTime");
var projection = Builders<BsonDocument>.Projection
.Include("_id")
.Include("fileName"); // for bravity i have removed other projection elements
var output = new List<IDictionary<string, string>>();
// How do i pass update filter and update the document at the same time??
await collection
.Find(filter)
.Sort(sort)
.Project(projection)
.ForEachAsync((unit) =>
{
var dictionary = new Dictionary<string, string>();
Recurse(unit, dictionary);
output.Add(dictionary);
});
return output.Count > 0 ? output : null;
}
That doesn't exist in the mongo .Net api see here.
Just use a combination of Find and UpdateManyAsync.

MongoDB c# driver slow find on index

Got a 50+ million of documents and non-unique index on field "Base.UserID"
Two mongo servers in replicaset and connection string :
<add name="MongoConnectionString" connectionString="mongodb://mango1,mango2:27017" />
Index insured:
var eventCollection = Collection<EventMongo>();
eventCollection.EnsureIndex(IndexKeys.Ascending("Base.UserID"), IndexOptions.SetName("Event.Base.UserID"));
Then I do find
var _Set = new SortedSet<Int64>();
using (var db = new BaseDataAccess())
{
var col = db.Collection<EventMongo>();
var counter = 0;
var query = Query.And(
Query.EQ("Base.UserID", UserID),
Query.EQ("Base.Visible", 1)
);
var _docs = col.Find(query);
_docs.SetFields(new[] {"SQLId"});
_docs.SetSortOrder(SortBy.Descending("SQLId"));
_docs.SetLimit(HowMany);
int i = 0;
foreach (var doc in _docs)
{
var _EventID = doc.SQLId;
_Set.Add(_EventID);
if (++counter >= HowMany) break;
}
}
return _Set;
Same documents contains a parrallel MS SQL db, and i mention that the first query for read to MongoDB takes more time (up to 5 seconds) than MS SQL !
(The second hit on the same UserID is faster)
Your index is not being used. If you are querying by "Base.UserID" and "Base.Visible", then you need a compound index with both fields.
"scanAndOrder" : true, you want this to be false if possible.
I believe you might want to add your sort to the index.
MongoBlog on Index Ordering
eventCollection.EnsureIndex(IndexKeys.Ascending("Base.UserID"), IndexKeys.Descending("SQLId"), IndexOptions.SetName("Event.Base.UserID"));

Facebook api search in Asp.mvc 3 app

EDITED
I'm searching users in facebook using graph api in my asp.net mvc 3 application.
public void AsyncSearch(ICollection<JSonObject> result, string query, string objectType)
{
var fbClient = new FacebookClient(FacebookTokens.AccessToken);
var searchUri = string.Format("/search?q={0}&type={1}, query, objectType);
var tempResult = (JsonObject)fbClient.Get(searchUri);
var elements = (JsonArray)tempResult.Values.ToArray()[0];
elements.ForEach(element =>
{
result.Add(element);
});
var next = (JsonObject)tempResult.Values.ToList()[1];
while (next.Keys.Contains("next"))
{
tempResult = (JsonObject)fbClient.Get((string)next["next"]);
elements = (JsonArray)tempResult.Values.ToArray()[0];
elements.ForEach(element =>
{
result.Add(element);
});
next = (JsonObject)tempResult.Values.ToList()[1];
}
}
But result contains at most 600 objects(each search returns different number of objects).
I think, if i put, for example, "anna" in query parameter - result must be over 10000.
Why is that? Is there any way to retrieve all users by some keyword?
For performance concerns Facebook will paginate their results. If you look at the end of the JSON object, there should be a pageing object that has next and previous links in it. So, to get all results you will need to run multiple queries and aggregate them up on your side.

Linq to Entity Framework 4 query counting but not returning results

I have a query like:
var fooQuery = (from x in edm.stuff where x.col == DesiredVal select x)
'stuff' is a view. When I count the results I get '1'. When I First() or FirstOrDefault() I get null.
var fooCount = fooQuery.Count(); // results in 1
var fooResult = fooQuery.FirstOrDefault(); // results in null
This doesn't make sense to me. Is there a circumstance that this should be happening?
are you using a private member in the where statement?