Creating a EntityIterable from multiple Entity objects

Tags: , ,



I’m trying to implement a “nearby” filter with Xodus, having this code:

AtomicReference<EntityIterable> referenceToScope = ...;
PropertyNearbyCondition propertyNearbyCondition = (PropertyNearbyCondition) entityCondition;
String propertyName = propertyNearbyCondition.propertyName();
Double longitude = propertyNearbyCondition.longitude();
Double latitude = propertyNearbyCondition.latitude();
Double distance = propertyNearbyCondition.distance();
EntityIterable entities =
    referenceToScope.get().intersect(txn.findWithProp(entityType, propertyName));
List<Entity> entityList = new ArrayList<>();
entities.forEach(entity -> {
  GeoPoint reference = (GeoPoint) entity.getProperty(propertyName);
  double instantaneousDistance =
      MathHelper.distFrom(latitude, longitude, reference.getLatitude(),
  reference.getLatitude());
  if (distance >= instantaneousDistance) {
    entityList.add(entity);
  }
});


EntityIterable scoped = referenceToScope.get().intersect(build(entityList));

EntityIterable build(List<Entity> entityList) {
   // TODO: Build a new EntityIterable from the entityList
}

The algorithm may not be the best, but, the main question here is how to build a new EntityIterable based from multiple Entity objects? Is that possible?

My solution to basically collect “nearby” entities is to iterate over all entities with the custom GeoPoint property then for each Entity found, comparing the distance of its GeoPoint property and if that is a hit then all these entities should be collected into one EntityIterable.

How do you build a EntityIterable from a list of Entity objects?

UPDATE:

Explaining how this works step-by-step:

This code below gets all the entities with the given property name, e.g. geoLocation

EntityIterable entities =
    referenceToScope.get().intersect(txn.findWithProp(entityType, propertyName));

Then for all the entities with such geoLocation property for example iterate over it to compute if it meets the distance target:

List<Entity> entityList = new ArrayList<>();
entities.forEach(entity -> {
   // compute the distance target
});

Adding the entity to the new List if it meets the target.

From here what needs to be done is to either remove all entities in the EntityIterable entities which does not equal to the ID’s of the matched entities in the entityList OR to intersect these matched entities to referenceToScope.get() and not to EntityIterable entities (just to avoid confusion, this entities iterable is a just a temp one)

Answer

Here’s how to solve this:

entities.forEach(entity -> {
  GeoPoint reference = (GeoPoint) entity.getProperty(propertyName);
  double instantaneousDistance =
      MathHelper.distFrom(latitude, longitude, reference.getLatitude(),
  reference.getLatitude());
  if (distance < instantaneousDistance) {
    referenceToScope.set(referenceToScope.get().minus(txn.getSingletonIterable(entity)));
  }
});

This will effectively remove all entities that fails to match the target distance.



Source: stackoverflow